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