Skip to main content

A Rooted API Error Family in TypeScript v4 SDKs (Beta)

· 2 min read

TypeScript v4 SDKs now reject with one error family. Every failure a call can produce derives from a single root named after your API, such as PaymentsError, and carries a closed kind discriminator, so one catch with a switch on err.kind handles every outcome exhaustively.

Details​

The six kinds are api for an error status, decode for a response that did not fit its declared type, encode for a request value that failed its schema before anything was sent, connection for a request that never got an answer, timeout for an attempt that ran out of time, and auth for a credential that could not be obtained. Every error names the method and URI of the call that raised it.

ApiError carries the status, the headers and a payload. An operation whose specification declares error responses rejects with its own subclass, such as Payments.CreateError, whose payload is a union of those declared bodies narrowed on payload.kind. A status the specification does not describe arrives as the undeclared arm, with the raw bytes in rawBody. Call .asApiResult() on an operation's promise to receive an error status as a value instead of a rejection.

ConfigurationError stays outside the family. The constructor throws it for a defect in the client options, such as an unknown server environment.

Usage Example​

Narrow the operation's own error on its payload, then the rest of the family on kind:

import { PaymentsClient, PaymentsError, Payments } from "payments";

const client = new PaymentsClient();

try {
await client.payments.create({ accountId: "acc_1", body: { amount: 1000, currency: "USD" } });
} catch (err) {
if (err instanceof Payments.CreateError) {
switch (err.payload.kind) {
case "paymentError":
console.error(err.status, err.payload.body.message);
break;
case "undeclared":
console.error(err.status, new TextDecoder().decode(err.payload.rawBody));
break;
}
} else if (err instanceof PaymentsError) {
console.error(`${err.kind}: ${err.message}`);
} else {
throw err;
}
}

A caller's abort is not part of the family and rejects with the signal's own reason.

This feature is available in the TypeScript v4 SDK (beta). Generate it from the APIMatic CLI:

apimatic sdk generate --language=typescript --codegen-version=v4 --stability=beta

For the full set of flags and options, see the APIMatic CLI documentation.