Customize error handling
This structured guide demonstrates how you can configure and customize error handling in Speakeasy-generated SDKs.
Default error handling (no configuration)
By default, Speakeasy SDKs handle errors as follows:
- Validation errors: If the server response doesn’t match the SDK’s expected data schema, validation errors are raised.
- 4XX and 5XX status codes: If a server response includes these status codes, it is treated as an error.
- Connection errors: If the SDK fails to connect to your server (DNS, timeouts, TLS errors), a connection-related error or exception is raised.
Example OpenAPI document
openapi: 3.1.0info:title: The Speakeasy Barversion: 1.0.0servers:- url: https://speakeasy.barpaths:/drinks:get:operationId: listDrinkssummary: Get a list of drinksresponses:"200":description: A list of drinkscontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Drink"components:schemas:Drink:type: objecttitle: Drinkproperties:name:type: string
TypeScript SDK default error handling
import { Drinks } from "drinks";import {SDKValidationError,SDKError,HTTPClientError,} from "drinks/models/errors/index.js";const drinks = new Drinks();async function run() {let result;try {result = await drinks.listDrinks();console.log(result);} catch (err) {// 1. Validation errors: Server response didn't match the SDK's expected data schemaif (err instanceof SDKValidationError) {// Raw value will be type `unknown`console.error(err.rawValue);// Validation errors can be pretty-printedconsole.error(err.pretty());return;}// 2. 4XX and 5XX status codes: Server returned an error code with an unexpected content type// Use `typescript.defaultErrorName` to change the name of `SDKError` in `gen.yaml`if (err instanceof SDKError) {console.error(err.statusCode);console.error(err.rawResponse.body);return;}// 3. Connection errors: The SDK didn't even get a response from the serverif (err instanceof HTTPClientError) {console.error(err.name);console.error(err.message);}throw err;}}
Recommended configuration
We recommend that you configure custom names, such as UnauthorizedError
or NotFoundError
, for certain error classes to improve the developer experience for the end user of your SDK. For example, given that APIs commonly return structured JSON errors for 4XX status codes, you could name 4XX errors by defining their responses in your OpenAPI document as follows:
openapi: 3.1.0info:title: The Speakeasy Barversion: 1.0.0servers:- url: https://speakeasy.barpaths:/drinks:get:operationId: listDrinkssummary: Get a list of drinksresponses:"200":description: A list of drinkscontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Drink""401":content:application/json:schema:$ref: "#/components/schemas/UnauthorizedError""403":content:application/json:schema:$ref: "#/components/schemas/ForbiddenError""404":content:application/json:schema:$ref: "#/components/schemas/NotFoundError""429":content:application/json:schema:$ref: "#/components/schemas/TooManyRequestsError"components:schemas:Drink:type: objecttitle: Drinkproperties:name:type: stringUnauthorizedError:type: objecttitle: UnauthorizedErrorproperties:message:type: stringx-speakeasy-error-message: trueForbiddenError:type: objecttitle: ForbiddenErrorproperties:message:type: stringx-speakeasy-error-message: trueNotFoundError:type: objecttitle: NotFoundErrorproperties:message:type: stringx-speakeasy-error-message: trueTooManyRequestsError:type: objecttitle: TooManyRequestsErrorproperties:message:type: stringx-speakeasy-error-message: true
Note that we use x-speakeasy-error-message: true
to configure the error message used by the SDK, which will be propagated to err.message
in the SDK.
We don’t recommend defining 5XX responses in this way, as your server is not always in control of these responses. If you do specify a JSON schema for a 5XX response, and the response doesn’t match the schema, the SDK will raise an SDKValidationError
.
TypeScript SDK default error handling
import { Drinks } from "drinks";import {SDKValidationError,SDKError,HTTPClientError,UnauthorizedError,ForbiddenError,NotFoundError,TooManyRequestsError,} from "drinks/models/errors/index.js";const drinks = new Drinks();async function run() {let result;try {result = await drinks.listDrinks();console.log(result);} catch (err) {// Unauthorizedif (err instanceof UnauthorizedError) {console.error(err.message);return;}// Forbiddenif (err instanceof ForbiddenError) {console.error(err.message);return;}// Not foundif (err instanceof NotFoundError) {console.error(err.message);return;}// Too many requestsif (err instanceof TooManyRequestsError) {console.error(err.message);return;}// 1. Validation errors: Server response didn't match the SDK's expected data schemaif (err instanceof SDKValidationError) {// Raw value will be type `string`console.error(err.rawValue);// Validation errors can be pretty-printedconsole.error(err.pretty());return;}// 2. 4XX and 5XX status codes: Server returned an error code with an unexpected content type// Use `typescript.defaultErrorName` to change the name of `SDKError` in `gen.yaml`if (err instanceof SDKError) {console.error(err.statusCode);console.error(err.rawResponse.body);return;}// 3. Connection errors: The SDK didn't even get a response from the serverif (err instanceof HTTPClientError) {console.error(err.name);console.error(err.message);}throw err;}}
Advanced configuration
Renaming generated error classes
Unhandled API errors raise an exception of the default SDKError
, APIError
, or APIException
class (depending on the SDK language). You can change the name of the default error class by editing the defaultErrorName
parameter in your gen.yaml
file for the corresponding SDK language:
python:defaultErrorName: MyError
To rename other generated error classes, please consult the Customizing types documentation.
Handling the default error response
The default
response code is a catch-all for any status code that is not explicitly defined. Speakeasy SDKs automatically treat default
responses as non-error responses. To treat them as a specific error type, define a new default response in the x-speakeasy-errors
extension on any operation:
x-speakeasy-errors:statusCodes:- "default"
Disabling default error handling
In certain cases, you may want to disable the default error-handling behavior of SDKs. For example, you may not want to throw an error for a 404 status code.
You can override this default behavior by adding the x-speakeasy-errors
extension at the paths
, path item
, or operation
level. Deeper levels merge or override parent behavior.
The x-speakeasy-errors
extension is an object with the following properties:
Property | Type | Description |
---|---|---|
override | boolean | If true , the statusCodes list overrides any parent x-speakeasy-errors extension for this object and its children. Defaults to false . |
statusCodes | [string] | An array of status codes to handle as errors. It merges with any parent x-speakeasy-errors extension unless override is true . Each status code must be in quotation marks (for example, "503" ) for JSON and YAML compatibility. Wildcards (like 5XX ) are supported. |
If the statusCodes
array contains undocumented status codes, the SDK returns an SDK error object containing the status code, the response body as a string, and the raw response object. Otherwise, if the content-type
is application/json
, it returns an error object from the response object in the OpenAPI document.
For example:
paths:x-speakeasy-errors:statusCodes: # Defines status codes to handle as errors for all operations- 4XX # Wildcard to handle all status codes in the 400-499 range- 5XX/drinks:x-speakeasy-errors:override: true # Forces this path and its operations to only handle 404 and 500 as errors, overriding the parent x-speakeasy-errors extension at the paths levelstatusCodes:- 404- 500get:x-speakeasy-errors:statusCodes: # As override is not set to true, this operation will handle 404, 401, 500, and 503 as errors, merging with the parent x-speakeasy-errors extension at the path item level- 401- 503operationId: getDrinksresponses:200:description: OKcontent:application/json:schema:type: arrayitems:$ref: "#/components/schemas/Drink"401:description: Unauthorizedcontent:application/json: # As an application/json response is defined, the schema will generate a custom error object (for example `AuthError`) that will be returned and can be tested forschema:$ref: "#/components/schemas/AuthError"404:description: Not Found # As no application/json response is defined, the SDK will return a standard SDK error object.500:description: Internal Server Errorcontent:application/json:schema:$ref: "#/components/schemas/Error"503:description: Service Unavailable
Alternatively, you can disable default error handling by setting the clientServerStatusCodesAsErrors
option to false
in your gen.yaml
file for the relevant SDK language:
go:clientServerStatusCodesAsErrors: false