Error Handling
The API uses a centralized error handling mechanism via GlobalExceptionHandler. All errors follow a consistent response format.
Error Response Format
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": { ... }
}
}
HTTP Status Codes
| Status Code | Description | When Used |
|---|---|---|
200 OK | Success | Successful GET, PUT, DELETE operations |
201 Created | Resource created | Successful POST operations |
204 No Content | Success, no body | Some DELETE and action endpoints |
400 Bad Request | Invalid request | Validation errors, bad input |
401 Unauthorized | Not authenticated | Missing or invalid JWT token |
403 Forbidden | Access denied | Insufficient role/permissions |
404 Not Found | Resource not found | Entity doesn't exist |
500 Internal Server Error | Server error | Unexpected server errors |
Exception Types
BadRequestException
Thrown when the request is malformed or contains invalid data.
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Title must be less than 500 characters"
}
}
UnauthorizedException
Thrown when authentication fails.
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired token"
}
}
AccessDeniedException
Thrown when the user lacks required permissions.
{
"success": false,
"error": {
"code": "ACCESS_DENIED",
"message": "You do not have permission to perform this action"
}
}
ResourceNotFoundException
Thrown when the requested resource doesn't exist.
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Document not found with id: 550e8400-..."
}
}
BusinessException
Thrown for business logic violations.
{
"success": false,
"error": {
"code": "BUSINESS_ERROR",
"message": "Cannot transfer ownership to a non-member"
}
}
Validation Errors
When request body validation fails (JSR 380 / Jakarta Validation), the response includes field-level details:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"name": "Name is required",
"email": "Invalid email format"
}
}
}
Common Error Scenarios
| Scenario | Status | Code |
|---|---|---|
| Invalid JWT token | 401 | UNAUTHORIZED |
| Token expired | 401 | UNAUTHORIZED |
| User not a workspace member | 403 | ACCESS_DENIED |
| Viewer tries to edit | 403 | ACCESS_DENIED |
| Document not found | 404 | NOT_FOUND |
| Workspace not found | 404 | NOT_FOUND |
| Duplicate invitation | 400 | BAD_REQUEST |
| Owner tries to leave workspace | 400 | BUSINESS_ERROR |
| Invalid export format | 400 | BAD_REQUEST |
| File upload too large | 400 | BAD_REQUEST |