ToKnownError (ExceptionHandler)¶
ExceptionHandler.ToKnownError is the final step in translating an HTTP failure into a caller-meaningful domain exception, drawn from SAIF.Web.API.Core's SAIF.API.Exceptions.* hierarchy.
| Field | Value |
|---|---|
| Operation ID | OP-09 |
| Trigger | EnsureSuccessfulResponse step 4; also directly callable by consumers (public static). |
| Inputs | HttpStatusCode status, raw response content. |
| Outputs | Always throws. |
| Primary components | ExceptionHandler.ToKnownError(HttpStatusCode, string) |
| Entry point | src/SAIF.Web.API.Clients/ExceptionHandler.cs |
Steps¶
- If
contentis non-empty,JToken.Parse(content)and iterate its tokens (BR-CLI-008). - On failure:
catch { sb.Append(content); }— a parse failure makes the raw content the message. - For each token whose
Path(lower-cased) is one oferrormessage,exceptionmessage,message,usermessage, appendtoken.First.ToString()(BR-CLI-008). - Matching is on the token path, so only top-level properties with those names are harvested. Multiple matches are concatenated as separate lines.
- If nothing was harvested (blank builder), fall back to the raw
content(BR-CLI-008). - Guarantees a non-empty message whenever content was non-empty.
switch (status):404→NoMatchingDataException;403or401→SAIF.API.Exceptions.UnauthorizedAccessException;400→InvalidDataException; default (all other statuses, including0) →InternalServerError. SetHttpStatusCode = statuson the thrown instance (BR-CLI-007).- The thrown exception types are constructed in SAIF.Web.API.Core (
src/SAIF.Web.API.Core/SAIFException.cs): each constructor calls the baseException(string)constructor with a default message, and theHttpStatusCodeproperty is set by object initializer — no further logic. - Always throws; never returns.
Process flow¶
The following diagrams visualize this operation's control flow, split by concern so each renders at a readable width.
The first diagram shows message harvesting/fallback and the 404/401 or 403 status outcomes:
flowchart TD
Start([ToKnownError called]) --> Parse[Parse content as JToken]
Parse --> Harvest["Harvest<br>errormessage/<br>exceptionmessage/<br>message/usermessage<br>tokens"]
Harvest --> Fallback{Message harvested?}
Fallback -->|No| RawContent[Fall back to raw content]
Fallback -->|Yes| Switch
RawContent --> Switch{status?}
Switch -->|404| NoMatch(["Throw<br>NoMatchingDataException"])
Switch -->|401 or 403| Unauth(["Throw<br>UnauthorizedAccess<br>Exception"])
The second diagram shows the remaining 400 and other status outcomes:
flowchart TD
Switch{status?} -->|400| Invalid(["Throw<br>InvalidDataException"])
Switch -->|other| Internal(["Throw<br>InternalServerError"])
Failure and edge-case behavior¶
- A non-JSON or malformed
contentfalls back to the raw content as the exception message (step 1). - Status codes other than
400/401/403/404— including0(transport failure) — map toInternalServerError.
Related documentation¶
Sources¶
src/SAIF.Web.API.Clients/ExceptionHandler.cssrc/SAIF.Web.API.Core/SAIFException.cs