Ga naar hoofdinhoud

Error Handling

How the Ever Gauzy API handles errors and how to interpret error responses.

Error Response Formatโ€‹

All error responses follow a consistent structure:

{
"statusCode": 400,
"message": "Error description",
"error": "Bad Request"
}

For validation errors, message may be an array:

{
"statusCode": 400,
"message": [
"firstName must be a string",
"firstName should not be empty",
"email must be an email"
],
"error": "Bad Request"
}

HTTP Status Codesโ€‹

Client Errors (4xx)โ€‹

CodeNameDescriptionCommon Cause
400Bad RequestInvalid request body or parametersValidation failure, malformed JSON
401UnauthorizedAuthentication required or failedMissing/invalid JWT token
403ForbiddenAuthenticated but not authorizedInsufficient role/permissions
404Not FoundResource does not existWrong ID, deleted resource
405Method Not AllowedWrong HTTP methodUsing GET instead of POST
409ConflictDuplicate or conflicting resourceUnique constraint violation
422Unprocessable EntityValid syntax but semantic errorBusiness logic violation
429Too Many RequestsRate limit exceededToo many API calls

Server Errors (5xx)โ€‹

CodeNameDescription
500Internal Server ErrorUnexpected server error
502Bad GatewayUpstream service unavailable
503Service UnavailableServer overloaded or maintenance

Common Error Scenariosโ€‹

Authentication Errorsโ€‹

Invalid credentials:

{
"statusCode": 401,
"message": "Incorrect email or password",
"error": "Unauthorized"
}

Expired token:

{
"statusCode": 401,
"message": "Token has expired",
"error": "Unauthorized"
}

Missing token:

{
"statusCode": 401,
"message": "Unauthorized"
}

Permission Errorsโ€‹

Insufficient permissions:

{
"statusCode": 403,
"message": "You do not have permission to access this resource",
"error": "Forbidden"
}

Wrong tenant:

{
"statusCode": 403,
"message": "You do not have access to this tenant",
"error": "Forbidden"
}

Validation Errorsโ€‹

Missing required field:

{
"statusCode": 400,
"message": ["name should not be empty", "name must be a string"],
"error": "Bad Request"
}

Invalid UUID:

{
"statusCode": 400,
"message": ["organizationId must be a UUID"],
"error": "Bad Request"
}

Not Found Errorsโ€‹

Resource not found:

{
"statusCode": 404,
"message": "Record not found",
"error": "Not Found"
}

Conflict Errorsโ€‹

Duplicate entry:

{
"statusCode": 409,
"message": "Email already exists",
"error": "Conflict"
}

Error Handling in NestJSโ€‹

The backend uses NestJS built-in exception classes:

// 400
throw new BadRequestException("Invalid input");

// 401
throw new UnauthorizedException("Token expired");

// 403
throw new ForbiddenException("Insufficient permissions");

// 404
throw new NotFoundException("Employee not found");

// 409
throw new ConflictException("Email already exists");

Retry Strategyโ€‹

For transient errors (5xx, network timeouts), implement exponential backoff:

async function apiCallWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options);
if (response.status >= 500)
throw new Error(`Server error: ${response.status}`);
return response;
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise((resolve) =>
setTimeout(resolve, Math.pow(2, i) * 1000),
);
}
}
}

When to Retryโ€‹

ErrorRetry?Notes
400 Bad RequestโŒFix the request
401 UnauthorizedโŒRe-authenticate
403 ForbiddenโŒCheck permissions
404 Not FoundโŒCheck resource ID
409 ConflictโŒResolve conflict
429 Rate Limitedโœ…Wait and retry
500 Server Errorโœ…Retry with backoff
502 Bad Gatewayโœ…Retry with backoff
503 Unavailableโœ…Retry with backoff