EH-BR-04 Status code and content type come exactly from the caller¶
Field
Value
Statement
The response status code and content type are exactly those supplied by the caller. For HttpStatusCodeException they come from the exception; otherwise they are 500 / text/plain.
Trigger
LogAndReturnException
Enforcement
ErrorHandler.LogAndReturnException; values chosen in ErrorHandler.Invoke (legacy) or DynamicErrorHandler.InvokeAsync (ServiceExtensions)
EH-BR-05 Handled-exception body format depends on content type¶
Field
Value
Statement
For a handled exception, a non-text/plain content type (for example JSON or XML) gets the raw ex.Message as the body so the payload format is preserved. A text/plain content type gets the message followed by "\nPlease see error: {ErrorID}."
EH-BR-08 Exception classification precedence for HTTP hosts¶
Field
Value
Statement
Exception classification precedence: HttpStatusCodeException (handled, own status and content type, log details), then SAIFException (handled, 500, text/plain, log details), then any other exception (unhandled, 500, text/plain).
Trigger
Exception from the downstream pipeline
Enforcement
ErrorHandler.Invoke (legacy); re-implemented in DynamicErrorHandler.InvokeAsync (ServiceExtensions)
Outcome
Selects the isHandled, status, and content type for the response
EH-BR-11 A BeginErrorHandling subscriber may suppress logging or actions¶
Field
Value
Statement
A BeginErrorHandling subscriber may suppress logging (Handled = true) and/or suppress special actions (FireSpecialActions = false). By default both run.
Trigger
HandleError
Enforcement
WindowsServiceErrorHandler.HandleError; defaults in ServiceContracts BeginErrorHandlingEventArgs
EH-BR-12 Special actions run in registration order and continue after a Fail result only if failure logging succeeds¶
Field
Value
Statement
When special actions fire, each registered action runs in order, and execution proceeds to the next action after a Fail result only if the Error-level failure-logging call for that result does not itself throw. A thrown fire-condition predicate, a custom ISpecialErrorAction.Invoke override that throws, or a throwing logger call all stop the loop early, preventing any remaining actions — and the subsequent ErrorHandled event — from running.
Trigger
FireSpecialActions == true
Enforcement
WindowsServiceErrorHandler.HandleError
Outcome
All results collected only when no action, predicate, or failure-logging call throws; otherwise the loop and HandleError itself terminate early
EH-BR-14 ErrorHandled is raised after handling completes without an earlier escape¶
Field
Value
Statement
After the special-actions loop finishes, ErrorHandled is raised with the exception, the Handled flag, all collected action results, and the context container — but only if nothing earlier in HandleError (the BeginErrorHandling subscribers, the initial Error-level log call, a fire-condition predicate, a custom action, or a failure-logging call) threw and escaped first (see EH-BR-12).
Trigger
End of HandleError, reached only when no earlier step threw
Enforcement
WindowsServiceErrorHandler.OnErrorHandled
Outcome
Subscribers notified when HandleError runs to completion; otherwise the exception propagates out of HandleError and no ErrorHandled event fires
EH-BR-17 The built-in action wrapper catches only its own wrapped delegate¶
Field
Value
Statement
The base SpecialErrorAction.Invoke catches an exception only from the wrapped invoke delegate call itself, returning it as a Fail result. The fire-condition predicate (testFireCondition) is evaluated outside that try block, so a throwing predicate propagates out of Invoke uncaught. A custom type that implements ISpecialErrorAction/overrides Invoke directly (such as SpecialErrorAction<T>'s own overridden Invoke body before it delegates to the base) is not bound by this containment at all.
Trigger
Delegate throws (caught); predicate or an overriding Invoke throws (not caught)
Enforcement
SpecialErrorAction.Invoke
Outcome
Success/Fail result for a wrapped-delegate exception; an uncaught exception for a predicate or non-conforming override, which stops the enclosing action loop (see EH-BR-12)
EH-BR-18 Windows Service error ID format and lazy generation¶
Field
Value
Statement
A Windows Service error ID is {GUID}-{yyyyMMddHHmmssffffzzz} with : replaced by -. It is generated once, on first access, and that access stamps ErrorTime.
EH-BR-19 Logged Windows Service error text always includes a fixed field set¶
Field
Value
Statement
The logged Windows Service error text always includes the ID, current time, application, host, track, machine, user@domain, source, exception name, message, and stack trace, plus log details when present.
Rules enforced outside this library over this library's data¶
Shutdown exemption. The service stops unless the exception's exact type is listed in ShutdownExemptExceptionTypes and that entry's IsAllowed(ex) returns true. This is enforced by SAIF.NetCore.WindowsService.ServiceWorker.IsExceptionExemptFromShutdown (src/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/SAIF.NetCore.WindowsService/ServiceWorker.cs), not by this library.
Hook failure aggregation. If any IErrorHandlerHook throws, ErrorHandler receives an AggregateException (hook exceptions plus the original) instead of the original. This is enforced by SAIF.NetCore.ServiceExtensions.Middleware.DynamicErrorHandler.LogAndReturnException (src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/Middleware/DynamicErrorHandler.cs), not by this library.