API FEATURE
Structured Errors
API failures should stay operationally useful. This page shows the exact error body a client would parse, not just the fact that the request failed.
Feature Guide
A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.
What this does
Structured Errors demonstrates that Semitexa API failures stay machine-readable even when the route throws domain exceptions.
How it works
The route throws typed domain exceptions, and ExternalApiExceptionMapper turns them into one JSON envelope with a stable `error.code`, human message, structured context, and optional retry metadata.
Why it matters
API clients need more than a string message. A stable envelope lets SDKs, dashboards, and background jobs branch on error semantics without scraping text.
Key concepts
- ExternalApiExceptionMapper
- Maps domain exceptions on external API routes into stable JSON error envelopes.
- error.context
- Structured machine-readable metadata that explains the failure without parsing the message.
- request_id
- Correlation id slot for tracing a failing API request across logs and support channels.
Failure Contract
Not-found envelope
The route throws a domain exception, but the external API pipeline still returns one predictable error envelope.
GET /demo/api/structured-errors?type=not-found
404 application/json
curl -H "Accept: application/json" "http://localhost:9502/demo/api/structured-errors?type=not-found"
| Header | Value |
|---|---|
Content-Type |
application/json |
Machine-readable error body
{
"error": {
"code": "not_found",
"message": "Demo API product #missing-product not found.",
"context": {
"resource": "Demo API product",
"identifier": "missing-product"
},
"request_id": null,
"docs_url": null
}
}
Verified against Semitexa Ultimate 2026.09.19.1020
Structured Errors
API failures should stay operationally useful. The ExternalApiExceptionMapper intercepts any DomainException thrown from an #[ExternalApi] route and transforms it into a predictable JSON error envelope before the response leaves the framework.
How it works
Domain exceptions carry typed context — field errors for validation failures, retry_after for rate limits, resource identifiers for not-found cases. The mapper reads that context and places it under error.context in the response body. The HTTP status code maps directly from the exception type. The outer envelope shape is always { error: { code, message, context, request_id, docs_url } }.
Why this matters
Clients can rely on error structure even when the business path fails. Validation problems stay nested under error.context.fields, auth failures keep the same outer shape with only the status changing, and retry guidance appears in both the Retry-After header and the machine-readable body. SDKs and dashboards can branch on error.code with one parser instead of two.
How it works
The route throws typed domain exceptions, and ExternalApiExceptionMapper turns them into one JSON envelope with a stable `error.code`, human message, structured context, and optional retry metadata.
Why it matters
API clients need more than a string message. A stable envelope lets SDKs, dashboards, and background jobs branch on error semantics without scraping text.
Key concepts
- ExternalApiExceptionMapper
- Maps domain exceptions on external API routes into stable JSON error envelopes.
- error.context
- Structured machine-readable metadata that explains the failure without parsing the message.
- request_id
- Correlation id slot for tracing a failing API request across logs and support channels.