---
title: Translate HTTP failure to typed exception
summary: Map an unsuccessful HTTP response to a typed SAIFException subtype.
status: draft
owner: bendy
last_reviewed: 2026-09-15
library: SAIF.Web.API.Clients.35
reference_type: package
operation_id: OP-03
trigger: Step 9 of the request operation, when EnsureSuccessfulResponse is true
---

# Translate HTTP failure to typed exception

This operation inspects an `IRestResponse`'s status code and body, and either returns normally (success) or throws a specific `SAIFException` subtype carrying the original HTTP status code.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-03 |
| **Trigger** | Step 9 of [Execute JSON API request and return typed envelope](op-01-execute-json-api-request.md), when `EnsureSuccessfulResponse` is true; also directly callable as `ToKnownError`. |
| **Inputs** | `IRestResponse` (status code and body content). |
| **Outputs** | A thrown `SAIFException` subtype carrying `HttpStatusCode`; returns normally when the status is 200–399. |
| **Primary components** | `ExceptionHandler.EnsureSuccessfulResponse`, `ExceptionHandler.ToKnownError`, `ExceptionHandler.GetContent` |
| **Entry point** | src/SAIF.Web.API.Clients/ExceptionHandler.cs |

## Steps

1. Evaluate status: `status < 200 || status >= 400` → continue; otherwise return normally ([BR-16](../business-rules.md#br-16-success-status-range)).
2. Select message source (`GetContent`): `response.Content` when nonblank; otherwise a fallback chain that does not reliably return `ErrorMessage`/`ErrorException.Message` as a clean precedence — see [BR-17](../business-rules.md#br-17-error-message-source-selection) for the verified branch-by-branch behavior, including the apparent defect where a lone nonblank `ErrorMessage` or a lone `ErrorException` is discarded.
   - This step delegates to a package dependency operation retrieved via the Legends CLI RAG service.
   - Checks whether the candidate message is null or whitespace-only.†

   > **Origin**: Step 2.1† is implemented in `IsNullOrWhiteSpace` in `SAIF.Framework.Common` (retrieved via the Legends CLI RAG service) and executed on behalf of this operation.
3. Parse structured error: `JToken.Parse(content)`; accumulate tokens whose path is `errormessage`, `exceptionmessage`, `message`, or `usermessage` (case-insensitive) ([BR-18](../business-rules.md#br-18-recognized-error-property-names)).
4. Fallback message: if the accumulated text is blank, or parsing threw, use the raw content ([BR-19](../business-rules.md#br-19-fallback-to-raw-body-on-parse-failure)).
5. Map to exception type: 404 → `NoMatchingDataException`; 401/403 → `UnauthorizedAccessException`; 400 → `InvalidDataException`; all other statuses → `InternalServerError`; each initialized with `HttpStatusCode = status` ([BR-20](../business-rules.md#br-20-http-status-to-exception-type-mapping)).
   - Constructs the selected exception type from the [`SAIFException`](../../saif-web-api-core/api/SAIF.API.Exceptions/SAIFException.md) hierarchy defined in `SAIF.Web.API.Core`, an in-run local project dependency.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Response received]) --> D1{Status in 200-399?}
	D1 -->|Yes| EndOk([Return normally])
	D1 -->|No| S1[Select message source]
	S1 --> S2["Parse structured error<br>content"]
	S2 --> D2{Message extracted?}
	D2 -->|No| S3[Fall back to raw content]
	D2 -->|Yes| S4["Map status to exception<br>type"]
	S3 --> S4
	S4 --> EndErr(["Throw typed<br>SAIFException"])
```

## Failure and edge-case behavior
- 401 (`Unauthorized`) is included in the default `RetryOnStatusCodes` set consumed by [Execute JSON API request and return typed envelope](op-01-execute-json-api-request.md), so an authentication failure is retried up to 3 times (with a 1-second default delay) before this operation raises the exception.

> **Note:** Statements marked with `†` were retrieved from dependency library documentation
> via the Legends CLI RAG service. They describe inherited behavior from the indicated
> origin library and should be verified if the dependency version changes.

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

## Sources
- src/SAIF.Web.API.Clients/ExceptionHandler.cs
- src/SAIF.Web.API.Core/SAIFException.cs
