Skip to content

Error Handling

The SDK transforms all API errors into typed error classes with rich metadata. All errors extend SonarSDKError.

Error Class Hierarchy

SonarSDKError (base)
β”œβ”€β”€ AuthenticationError (401/403)
β”œβ”€β”€ RateLimitError (429)
β”œβ”€β”€ DocumentNotFoundError (404)
└── ValidationError (400)

Base Error β€” SonarSDKError

All SDK errors extend this base class.

PropertyTypeDescription
messagestringHuman-readable error message
codeErrorCode | stringMachine-readable error code
statusnumber?HTTP status code
requestIdstring?Unique request identifier for debugging
detailsRecord<string, unknown>?Additional error context
errorsFieldError[]?Array of field-level validation errors
timestampstringISO 8601 timestamp when the error was created

Methods: toJSON() β€” Serializes the error to a plain object.

try {
await sdk.documents.get('invalid_id');
} catch (err) {
if (err instanceof SonarSDKError) {
console.log(err.code); // "DOCUMENT_NOT_FOUND"
console.log(err.status); // 404
console.log(err.requestId); // "req_abc123"
console.log(err.timestamp); // "2025-06-01T12:00:00.000Z"
console.log(err.toJSON()); // serialized error object
}
}

AuthenticationError

Thrown for authentication and authorization failures (HTTP 401/403).

Common Causes:

  • Missing API key
  • API key doesn’t start with sk_
  • Expired or revoked API key
  • Insufficient permissions for the requested operation
import { AuthenticationError } from '@sonar/sdk';
try {
const sdk = new SonarSDK({ apiKey: 'bad_key', instanceName: 'demo' });
} catch (err) {
if (err instanceof AuthenticationError) {
console.log(err.message); // "API key must start with \"sk_\""
console.log(err.code); // "INVALID_API_KEY"
}
}

RateLimitError

Thrown when the API rate limit is exceeded (HTTP 429).

PropertyTypeDescription
codestringAlways 'RATE_LIMIT_EXCEEDED'
retryAfternumber?Seconds to wait before retrying
import { RateLimitError } from '@sonar/sdk';
try {
await sdk.documents.list();
} catch (err) {
if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${err.retryAfter} seconds`);
await new Promise(r => setTimeout(r, (err.retryAfter || 60) * 1000));
}
}

DocumentNotFoundError

Thrown when a requested document does not exist (HTTP 404).

PropertyTypeDescription
codestringAlways 'DOCUMENT_NOT_FOUND'
statusnumberAlways 404
documentIdstringThe ID that was not found
import { DocumentNotFoundError } from '@sonar/sdk';
try {
await sdk.documents.get('doc_nonexistent');
} catch (err) {
if (err instanceof DocumentNotFoundError) {
console.log(`Document ${err.documentId} not found`);
}
}

ValidationError

Thrown for client-side or server-side validation failures (HTTP 400).

PropertyTypeDescription
codestringAlways 'INVALID_REQUEST'
statusnumberAlways 400
errorsFieldError[]?Array of field-level errors

Each FieldError: { field: string; code: string; message: string }

import { ValidationError } from '@sonar/sdk';
try {
await sdk.documents.export({ documentIds: [] });
} catch (err) {
if (err instanceof ValidationError) {
console.log(err.message); // "At least one document ID is required"
if (err.errors) {
err.errors.forEach(e => {
console.log(` ${e.field}: ${e.message} (${e.code})`);
});
}
}
}

Comprehensive Error Handling Pattern

import {
SonarSDK,
SonarSDKError,
AuthenticationError,
RateLimitError,
DocumentNotFoundError,
ValidationError,
} from '@sonar/sdk';
async function safeDocumentFetch(sdk: SonarSDK, id: string) {
try {
return await sdk.documents.get(id);
} catch (err) {
if (err instanceof DocumentNotFoundError) {
console.error(`Document ${err.documentId} does not exist`);
return null;
}
if (err instanceof AuthenticationError) {
console.error(`Auth failed: ${err.code} β€” ${err.message}`);
throw err;
}
if (err instanceof RateLimitError) {
const wait = err.retryAfter || 60;
console.warn(`Rate limited, retrying in ${wait}s...`);
await new Promise(r => setTimeout(r, wait * 1000));
return safeDocumentFetch(sdk, id);
}
if (err instanceof ValidationError) {
console.error('Validation error:', err.errors);
throw err;
}
if (err instanceof SonarSDKError) {
console.error(`SDK error [${err.code}]: ${err.message}`);
console.error(`Request ID: ${err.requestId}`);
throw err;
}
throw err;
}
}

Error Code Reference

Error CodeHTTP StatusError ClassDescription
MISSING_API_KEY401AuthenticationErrorNo API key provided
INVALID_API_KEY401AuthenticationErrorAPI key is malformed or invalid
EXPIRED_API_KEY401AuthenticationErrorAPI key has expired
REVOKED_API_KEY401AuthenticationErrorAPI key has been revoked
INSUFFICIENT_SCOPE403AuthenticationErrorAPI key lacks required permissions
IP_NOT_ALLOWED403AuthenticationErrorRequest IP is not in the allowlist
RATE_LIMIT_EXCEEDED429RateLimitErrorToo many requests
DOCUMENT_NOT_FOUND404DocumentNotFoundErrorRequested document does not exist
RESOURCE_NOT_FOUND404SonarSDKErrorGeneric resource not found
INVALID_REQUEST400ValidationErrorRequest validation failed
INVALID_PARAMETER400ValidationErrorSpecific parameter is invalid
EXPORT_LIMIT_EXCEEDED400ValidationErrorToo many documents requested for export
EXPORT_SIZE_EXCEEDED400ValidationErrorTotal export size exceeds limit
EXPORT_NO_FILES400ValidationErrorNo files found for the given document IDs
INTERNAL_ERROR500SonarSDKErrorUnexpected server error