Documentation Index Fetch the complete documentation index at: https://docs.devhelm.io/llms.txt
Use this file to discover all available pages before exploring further.
The SDK throws typed errors for API failures, validation issues, and network problems. The taxonomy mirrors the API’s ErrorResponse envelope, with subclasses per HTTP class for ergonomic catching.
Error class hierarchy
DevhelmError ← umbrella; catch as a fallback
├── DevhelmValidationError ← local request/response shape validation
├── DevhelmTransportError ← connection refused, DNS, TLS, timeout
└── DevhelmApiError ← non-2xx HTTP response
├── DevhelmAuthError ← 401, 403
├── DevhelmNotFoundError ← 404
├── DevhelmConflictError ← 409
├── DevhelmRateLimitError ← 429
└── DevhelmServerError ← 5xx
All classes are importable from the package root:
import {
DevhelmError ,
DevhelmValidationError ,
DevhelmApiError ,
DevhelmAuthError ,
DevhelmNotFoundError ,
DevhelmConflictError ,
DevhelmRateLimitError ,
DevhelmServerError ,
DevhelmTransportError ,
} from "@devhelm/sdk" ;
DevhelmApiError
The most common error class — thrown for any non-2xx HTTP response.
Property Type Description statusnumberHTTP status code (e.g. 404) codestringCoarse machine-readable category from ErrorResponse.code (e.g. "NOT_FOUND"). Defaults to "API_ERROR" if the server didn’t supply one. messagestringHuman-readable message — for logs and user-facing copy detailstring | undefinedAdditional context, when available bodyErrorResponse | undefinedParsed canonical error envelope if the body matched the contract rawBodyunknownRaw response body for debugging non-conforming responses requestIdstring | undefinedPer-request id from the X-Request-Id header. Always include in support tickets.
import { DevhelmApiError } from "@devhelm/sdk" ;
try {
await client . monitors . get ( "missing" );
} catch ( err ) {
if ( err instanceof DevhelmApiError ) {
console . error ( err . status ); // 404
console . error ( err . code ); // "NOT_FOUND"
console . error ( err . requestId ); // "req_01HJV..."
}
}
DevhelmValidationError
Thrown before HTTP I/O when a request body fails the Zod schema, and after a successful response when the response body doesn’t match the expected schema (rare — usually indicates a stale SDK).
Property Type Description messagestringSummary of the first 5 issues issuesReadonlyArray<ValidationIssue>Structured issues with path, message, and code
import { DevhelmValidationError } from "@devhelm/sdk" ;
try {
await client . monitors . create ({ type: "HTTP" } as any ); // missing fields
} catch ( err ) {
if ( err instanceof DevhelmValidationError ) {
for ( const issue of err . issues ) {
console . error ( ` ${ issue . path . join ( "." ) } : ${ issue . message } ` );
}
}
}
DevhelmTransportError
Thrown for network-level failures (connection refused, DNS, TLS handshake, timeout). The original fetch error is on .cause.
import { DevhelmTransportError } from "@devhelm/sdk" ;
try {
await client . monitors . list ();
} catch ( err ) {
if ( err instanceof DevhelmTransportError ) {
console . error ( "Network error:" , err . message );
console . error ( "Underlying:" , err . cause );
}
}
Handling patterns
Catch by HTTP class
import {
DevhelmAuthError ,
DevhelmNotFoundError ,
DevhelmRateLimitError ,
DevhelmError ,
} from "@devhelm/sdk" ;
try {
const monitor = await client . monitors . get ( monitorId );
} catch ( err ) {
if ( err instanceof DevhelmAuthError ) {
console . error ( "Bad token or insufficient permissions" );
} else if ( err instanceof DevhelmNotFoundError ) {
console . error ( `Monitor ${ monitorId } no longer exists` );
} else if ( err instanceof DevhelmRateLimitError ) {
console . error ( `Rate limited (request_id= ${ err . requestId } )` );
} else if ( err instanceof DevhelmError ) {
throw err ;
}
}
Retry on rate limits and 5xx
import {
DevhelmRateLimitError ,
DevhelmServerError ,
DevhelmTransportError ,
} from "@devhelm/sdk" ;
async function withRetry < T >(
fn : () => Promise < T >,
{ maxRetries = 3 , baseDelayMs = 1000 } = {},
) : Promise < T > {
for ( let attempt = 0 ; attempt <= maxRetries ; attempt ++ ) {
try {
return await fn ();
} catch ( err ) {
const retryable =
err instanceof DevhelmRateLimitError ||
err instanceof DevhelmServerError ||
err instanceof DevhelmTransportError ;
if ( ! retryable || attempt === maxRetries ) throw err ;
const delay = baseDelayMs * Math . pow ( 2 , attempt );
await new Promise (( r ) => setTimeout ( r , delay ));
}
}
throw new Error ( "unreachable" );
}
const monitors = await withRetry (() => client . monitors . list ());
Don’t retry on DevhelmValidationError, DevhelmAuthError, DevhelmNotFoundError, or DevhelmConflictError — these are deterministic and won’t change without code or config changes.
Deploy lock contention
import { DevhelmConflictError } from "@devhelm/sdk" ;
try {
const lock = await client . deployLock . acquire ({
lockedBy: "ci-pipeline" ,
ttlMinutes: 30 ,
});
} catch ( err ) {
if ( err instanceof DevhelmConflictError ) {
const current = await client . deployLock . current ();
console . error ( `Lock held by ${ current ?. lockedBy } (since ${ current ?. acquiredAt } )` );
}
}
Catch-all logging
import { DevhelmApiError , DevhelmError } from "@devhelm/sdk" ;
try {
await doWork ( client );
} catch ( err ) {
if ( err instanceof DevhelmApiError ) {
log . error ( "DevHelm API error" , {
status: err . status ,
code: err . code ,
requestId: err . requestId ,
detail: err . detail ,
});
} else if ( err instanceof DevhelmError ) {
log . error ( "DevHelm SDK error" , { message: err . message });
} else {
throw err ;
}
}
Next steps
Pagination Iterate through paginated results.
Error patterns Common error scenarios across all surfaces.