Exceptions
The WorkOS SDK throws specific exception types for different error scenarios. All exceptions implement the RequestException interface and extend the native Error class.
Exception Types
BadRequestException
Thrown when the API returns a 400 Bad Request status code.
Properties
Exception name: ‘BadRequestException’
Error message (default: ‘Bad request’)
Optional array of validation errors
Unique identifier for the request
Example
try {
await workos.userManagement.createUser({ email: 'invalid' });
} catch (error) {
if (error instanceof BadRequestException) {
console.error('Bad request:', error.message);
console.error('Request ID:', error.requestID);
console.error('Errors:', error.errors);
}
}
UnauthorizedException
Thrown when the API returns a 401 Unauthorized status code, typically due to an invalid API key.
Properties
Exception name: ‘UnauthorizedException’
Error message: ‘Could not authorize the request. Maybe your API key is invalid?’
Unique identifier for the request
Example
try {
const workos = new WorkOS('invalid_key');
await workos.userManagement.listUsers();
} catch (error) {
if (error instanceof UnauthorizedException) {
console.error('Authentication failed:', error.message);
console.error('Request ID:', error.requestID);
}
}
NotFoundException
Thrown when the API returns a 404 Not Found status code.
Properties
Exception name: ‘NotFoundException’
Error message (default: ‘The requested path '' could not be found.’)
Unique identifier for the request
Constructor Parameters
The requested path that was not found
Unique identifier for the request
Example
try {
await workos.userManagement.getUser('user_invalid');
} catch (error) {
if (error instanceof NotFoundException) {
console.error('Resource not found:', error.message);
console.error('Error code:', error.code);
}
}
UnprocessableEntityException
Thrown when the API returns a 422 Unprocessable Entity status code, typically due to validation errors.
Properties
Exception name: ‘UnprocessableEntityException’
Error message with validation requirements
Unique identifier for the request
Constructor Parameters
errors
UnprocessableEntityError[]
Array of validation errors
Unique identifier for the request
Example
try {
await workos.organizations.createOrganization({
name: '', // Invalid: empty name
});
} catch (error) {
if (error instanceof UnprocessableEntityException) {
console.error(error.message);
// Output: "The following requirement must be met:
// organization_name_required"
}
}
RateLimitExceededException
Thrown when the API returns a 429 Too Many Requests status code.
Properties
Exception name: ‘RateLimitExceededException’
Unique identifier for the request
The number of seconds to wait before retrying the request
Example
try {
await workos.userManagement.listUsers();
} catch (error) {
if (error instanceof RateLimitExceededException) {
console.error('Rate limit exceeded');
console.error(`Retry after ${error.retryAfter} seconds`);
if (error.retryAfter) {
setTimeout(() => {
// Retry the request
}, error.retryAfter * 1000);
}
}
}
OauthException
Thrown when OAuth authentication errors occur.
Properties
Exception name: ‘OauthException’
Unique identifier for the request
error
string | undefined
required
OAuth error code
errorDescription
string | undefined
required
Detailed error description
Example
try {
await workos.userManagement.authenticateWithCode({
code: 'invalid_code',
clientId: 'client_123',
});
} catch (error) {
if (error instanceof OauthException) {
console.error('OAuth error:', error.error);
console.error('Description:', error.errorDescription);
console.error('Status:', error.status);
}
}
GenericServerException
Thrown for generic server errors (5xx status codes).
Properties
Exception name: ‘GenericServerException’
Error message (default: ‘The request could not be completed.’)
Unique identifier for the request
Example
try {
await workos.userManagement.listUsers();
} catch (error) {
if (error instanceof GenericServerException) {
console.error('Server error:', error.message);
console.error('Status:', error.status);
console.error('Request ID:', error.requestID);
}
}
SignatureVerificationException
Thrown when webhook signature verification fails.
Properties
Exception name: ‘SignatureVerificationException’
Error message (default: ‘Signature verification failed.’)
Example
import { WorkOS } from '@workos-inc/node';
const workos = new WorkOS('sk_test_key');
try {
const webhook = workos.webhooks.constructEvent({
payload: requestBody,
sigHeader: request.headers['workos-signature'],
secret: 'webhook_secret',
});
} catch (error) {
if (error instanceof SignatureVerificationException) {
console.error('Invalid webhook signature:', error.message);
// Return 400 Bad Request
}
}
ApiKeyRequiredException
Thrown when an API key is required but not provided for a specific endpoint.
Properties
Exception name: ‘ApiKeyRequiredException’
Detailed error message with initialization instructions
The API path that requires an API key
Example
try {
const workos = new WorkOS(); // No API key provided
await workos.organizations.listOrganizations();
} catch (error) {
if (error instanceof ApiKeyRequiredException) {
console.error(error.message);
// Output: 'API key required for "/organizations".
// For server-side apps, initialize with: new WorkOS("sk_...").
// For browser/mobile/CLI apps, use authenticateWithCodeAndVerifier()...'
}
}
NoApiKeyProvidedException
Thrown when no API key is provided during SDK initialization.
Properties
Exception name: ‘NoApiKeyProvidedException’
Error message with instructions for providing an API key
Example
try {
const workos = new WorkOS();
} catch (error) {
if (error instanceof NoApiKeyProvidedException) {
console.error(error.message);
// Output: 'Missing API key. Pass it to the constructor (new WorkOS("sk_test_..."))
// or define it in the WORKOS_API_KEY environment variable.'
}
}
Error Handling Best Practices
Handle specific exceptions
import {
WorkOS,
UnauthorizedException,
NotFoundException,
RateLimitExceededException,
} from '@workos-inc/node';
const workos = new WorkOS('sk_test_key');
try {
const user = await workos.userManagement.getUser('user_123');
} catch (error) {
if (error instanceof UnauthorizedException) {
// Handle authentication error
console.error('Invalid API key');
} else if (error instanceof NotFoundException) {
// Handle not found error
console.error('User not found');
} else if (error instanceof RateLimitExceededException) {
// Handle rate limit with retry
await new Promise(resolve => setTimeout(resolve, error.retryAfter * 1000));
} else {
// Handle other errors
console.error('Unexpected error:', error);
}
}
Log request IDs for debugging
try {
await workos.userManagement.listUsers();
} catch (error) {
if ('requestID' in error) {
console.error(`Request failed. Request ID: ${error.requestID}`);
// Share this ID with WorkOS support for investigation
}
}
Implement retry logic
async function fetchWithRetry(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (error instanceof RateLimitExceededException && i < maxRetries - 1) {
const delay = error.retryAfter ? error.retryAfter * 1000 : 1000 * Math.pow(2, i);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
const users = await fetchWithRetry(() => workos.userManagement.listUsers());