Node.js SDK — Errors
The Node.js SDK defines a hierarchy of error classes for handling API errors. All error classes are importable from @pii-redactor/sdk.
Error Hierarchy
ApiError
├── AuthenticationError (401, 403)
├── NotFoundError (404)
├── ValidationError (422)
└── RateLimitError (429)
PollingTimeoutError (job polling exceeded timeout)ApiError
Base class for all API errors. Contains the HTTP status code, error message, and the raw response.
class ApiError extends Error {
statusCode: number;
message: string;
response?: Record<string, unknown>;
}| Property | Type | Description |
|---|---|---|
statusCode | number | HTTP status code |
message | string | Human-readable error message |
response | Record<string, unknown> | undefined | Raw JSON response body, if available |
AuthenticationError
Thrown when the API key is missing, invalid, or lacks the required scopes. Maps to HTTP 401 and 403 responses.
class AuthenticationError extends ApiError {}NotFoundError
Thrown when a requested resource (job, policy, API key) does not exist. Maps to HTTP 404.
class NotFoundError extends ApiError {}ValidationError
Thrown when the request body fails server-side validation. Maps to HTTP 422.
class ValidationError extends ApiError {}RateLimitError
Thrown when the API rate limit is exceeded. Maps to HTTP 429. Includes a retryAfter property indicating how many seconds to wait before retrying.
class RateLimitError extends ApiError {
retryAfter?: number;
}| Property | Type | Description |
|---|---|---|
retryAfter | number | undefined | Seconds to wait before retrying, from the Retry-After header |
PollingTimeoutError
Thrown when polling a job exceeds the maximum wait time. This is not an HTTP error — it is raised client-side when a job does not complete within the expected timeframe.
class PollingTimeoutError extends Error {
jobId: string;
elapsed: number;
}| Property | Type | Description |
|---|---|---|
jobId | string | ID of the job that timed out |
elapsed | number | Total milliseconds spent polling |
Error Handling Example
import {
PiiRedactor,
ApiError,
AuthenticationError,
NotFoundError,
RateLimitError,
ValidationError,
} from '@pii-redactor/sdk';
const client = new PiiRedactor({ apiKey: 'pk_live_...' });
try {
const result = await client.redact.text({
text: "John Smith's SSN is 123-45-6789",
});
} catch (e) {
if (e instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${e.retryAfter}s`);
} else if (e instanceof ValidationError) {
console.log(`Invalid request: ${e.message}`);
} else if (e instanceof AuthenticationError) {
console.log(`Auth failed: ${e.message}`);
} else if (e instanceof NotFoundError) {
console.log(`Resource not found: ${e.message}`);
} else if (e instanceof ApiError) {
console.log(`API error ${e.statusCode}: ${e.message}`);
}
}Handling Job Polling Timeout
import { PiiRedactor, waitForJob, PollingTimeoutError } from '@pii-redactor/sdk';
const client = new PiiRedactor({ apiKey: 'pk_live_...' });
try {
const job = await client.redact.uri({
inputUri: 's3://my-bucket/large-file.pdf',
});
const completed = await waitForJob(client, job.id, {
intervalMs: 2000,
timeoutMs: 60000,
});
console.log(`Job completed: ${completed.status}`);
} catch (e) {
if (e instanceof PollingTimeoutError) {
console.log(`Job ${e.jobId} did not complete after ${e.elapsed}ms`);
// Check status manually
const job = await client.jobs.get(e.jobId);
console.log(`Current status: ${job.status} (${job.progressPct}%)`);
}
}