Skip to main content

Error Handling

CORTEX uses RFC 7807 Problem Details for all error responses, providing consistent, machine-readable error information.

Error Response Format

{
"type": "https://api.cortex.purplelab.ai/errors/validation-error",
"title": "Validation Error",
"status": 400,
"detail": "Email is required",
"instance": "/auth/register"
}

Fields

FieldTypeDescription
typeURIA URI reference identifying the error type
titlestringA short, human-readable summary
statusnumberThe HTTP status code
detailstringA human-readable explanation
instancestringThe request path that caused the error

Additional Fields

Some errors include additional context:

{
"type": "https://api.cortex.purplelab.ai/errors/validation-error",
"title": "Validation Error",
"status": 400,
"detail": "Multiple validation errors occurred",
"instance": "/users",
"errors": [
{ "field": "email", "message": "must be a valid email" },
{ "field": "password", "message": "must be at least 8 characters" }
]
}

HTTP Status Codes

CodeMeaningCommon Causes
400Bad RequestValidation errors, malformed JSON
401UnauthorizedInvalid/expired token, missing auth
403ForbiddenInsufficient permissions
404Not FoundResource doesn't exist or access denied
409ConflictDuplicate resource, state conflict
422UnprocessableBusiness rule violation
429Too Many RequestsRate limit exceeded
500Internal ErrorServer-side error

Handling Errors

TypeScript

interface ProblemDetails {
type: string;
title: string;
status: number;
detail: string;
instance: string;
errors?: { field: string; message: string }[];
}

async function apiCall<T>(url: string, options?: RequestInit): Promise<T> {
const response = await fetch(url, options);

if (!response.ok) {
const error: ProblemDetails = await response.json();
throw new ApiError(error);
}

return response.json();
}

class ApiError extends Error {
constructor(public details: ProblemDetails) {
super(details.detail);
this.name = 'ApiError';
}

get status(): number {
return this.details.status;
}

get type(): string {
return this.details.type;
}
}

React Error Handling

function ErrorDisplay({ error }: { error: ApiError }) {
return (
<div className="error-container">
<h3>{error.details.title}</h3>
<p>{error.details.detail}</p>

{error.details.errors && (
<ul>
{error.details.errors.map((e, i) => (
<li key={i}>
<strong>{e.field}:</strong> {e.message}
</li>
))}
</ul>
)}
</div>
);
}

Why RFC 7807?

  1. Standardized — Industry-standard format supported by many tools
  2. Machine-Readable — Easy to parse programmatically
  3. Extensible — Can include additional context
  4. Self-Documenting — Type URIs can link to documentation