Перейти к основному содержимому

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 RequestFix the request
401 UnauthorizedRe-authenticate
403 ForbiddenCheck permissions
404 Not FoundCheck resource ID
409 ConflictResolve conflict
429 Rate LimitedWait and retry
500 Server ErrorRetry with backoff
502 Bad GatewayRetry with backoff
503 UnavailableRetry with backoff