---
title: Log exception
summary: Capture exception context, filter out known ASP.NET ViewState noise, and write the surviving error through the active sink.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-07-30
library: SAIF.Framework.Logging
reference_type: package
operation_id: LOG-OP-002
trigger: Caller invokes clsLogError.CreateError(...)
---

# Log exception

This is the library's primary error-recording path. It captures runtime context, flattens a possibly nested exception into a single formatted payload, discards known ASP.NET ViewState noise before it ever reaches a sink, and then writes any remaining error to the configured file sink or the remote logging SOAP service.

| Field | Value |
| --- | --- |
| **Operation ID** | LOG-OP-002 |
| **Trigger** | Caller invokes `clsLogError.CreateError(...)`. |
| **Inputs** | `Exception` plus optional state objects. |
| **Outputs** | `Boolean`; `False` only when the ViewState suppression filter matches, otherwise `True` even if the downstream write itself fails. |
| **Primary components** | `clsLogError.CreateError`, `clsLogError.GetErrorData`, `clsLogError.ExceptionToString`, `clsLogError.WriteMessage` |
| **Entry point** | `SAIF.Framework.Logging/clsLogError.vb` |

## Steps

1. Enter the outer `Try...Catch` in `CreateError(...)` so that any downstream failure is contained inside the logging library and never reaches the caller ([BR-005](../business-rules.md#br-005-logging-failures-must-never-raise-exceptions-to-the-caller)).
2. Construct `New clsLogError(inException, inStateInfo)` to assemble the error payload.
   - `GetErrorData()` captures machine, application, page, and environment fields from `HttpContext` for web callers or `Process.MainModule` for non-web callers, stamps `ErrorDate = Now`, and constructs the matching `clsSecurityPrincipal` platform instance.
   - When `Secprinc.IsAuthenticated` is `True`, copy `Secprinc.UserName` into `Username`; otherwise leave it empty.
   - `ExceptionToString(...)` walks to the innermost exception first, records its `Source` (or `UNKNOWN` when absent), then appends each exception's message, source, and stack trace using `EXCEPTIONINFOFORMAT`.
   - Serialize any supplied `inStateInfo` objects through `clsLogCommon.GetStateInfo(...)` and store the result in `StateInfo`.
   - On failure: helper-level exceptions are swallowed, and whatever fields were already populated are returned as-is ([BR-005](../business-rules.md#br-005-logging-failures-must-never-raise-exceptions-to-the-caller)).

   > **Origin**: The current-user lookup in step 2 delegates to `clsSecurityPrincipal`, documented in [Principal identity initialization](../../saif-framework-security/operations/principal-identity-initialization.md) (`SAIF.Framework.Security`).
3. Run `SuppressLogging()` against `ErrorInfo.ExceptionInfo` and stop immediately, returning `False`, when the formatted text contains `AUTHENTICATION OF VIEWSTATE FAILED` or `INVALID_VIEWSTATE_CLIENT_DISCONNECTED` ([BR-004](../business-rules.md#br-004-aspnet-viewstate-errors-are-never-logged)).
4. When the error is not suppressed, route it through `WriteMessage()`.
   - If `m_OutFile Is Nothing`, resolve `loggingServiceUrl`, construct `wsLogging.clsWSLogging`, map the payload into `wsLogging.ErrorInfoStruct`, call `WriteError(...)`, dispose the proxy, and swallow any resulting exception ([BR-005](../business-rules.md#br-005-logging-failures-must-never-raise-exceptions-to-the-caller)).
   - Otherwise append `ErrorInfoStruct.ToCSVString()` to the open file writer and flush it.

   > **Origin**: The `loggingServiceUrl` lookup in step 4 delegates to Environment API configuration retrieval, summarized in [Retrieve a configuration setting](../../saif-framework-security-environmentapi/operations/retrieve-configuration-setting.md) (`SAIF.Framework.Security.EnvironmentApi`).
5. Return `True` after the write attempt completes, or after the outer catch absorbs an unexpected exception — either way, the caller never has to handle a logging failure itself ([BR-005](../business-rules.md#br-005-logging-failures-must-never-raise-exceptions-to-the-caller)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([CreateError request]) --> Build[Build ErrorInfoStruct and exception text]
	Build --> Suppress{ViewState signature found?}
	Suppress -->|Yes| EndDrop([Return False])
	Suppress -->|No| Sink{File sink active?}
	Sink -->|Yes| FileWrite[Append CSV row and flush]
	Sink -->|No| Resolve[Resolve loggingServiceUrl]
	Resolve --> SoapWrite[Call wsLogging.WriteError]
	FileWrite --> EndOk([Return True])
	SoapWrite --> EndOk
```

## Failure and edge-case behavior

- ViewState-disconnect and ViewState-authentication failures are intentionally dropped before either sink is touched, keeping this class of noise out of both the log file and the SOAP endpoint ([BR-004](../business-rules.md#br-004-aspnet-viewstate-errors-are-never-logged)).
- The method returns `True` after most failures, because the outer catch swallows unexpected exceptions rather than propagating them — a `True` result does not guarantee the error was actually persisted ([BR-005](../business-rules.md#br-005-logging-failures-must-never-raise-exceptions-to-the-caller)).
- When a file sink is active, the remote SOAP path is skipped entirely for that call.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Configuration](../configuration.md)

## Sources
- `SAIF.Framework.Logging/clsLogError.vb`
- `SAIF.Framework.Logging/ErrorInfoStruct.vb`
- `SAIF.Framework.Logging/clsLogCommon.vb`
- `SAIF.Framework.Security/clsSecurityPrincipal.vb`
- `SAIF.Framework.Security.EnvironmentApi/Services.Common/EnvironmentServiceBase.cs`
- `SAIF.Framework.Security.EnvironmentApi/Services.Common/EnvironmentConfigKeys.cs`
