Skip to main content

Overview

The API uses a standardized error handling system that returns consistent error responses across all endpoints. All errors include a success: false flag and a descriptive error message.

Standard Error Response Format

All error responses follow this structure:
{
  "success": false,
  "error": "Error message describing what went wrong"
}

HTTP Status Codes

The API uses standard HTTP status codes to indicate the type of error:
Status CodeMeaningCommon Causes
400Bad RequestInvalid input data, validation errors, malformed requests
401UnauthorizedMissing or invalid authentication token
403ForbiddenInsufficient permissions (e.g., trying to edit someone else’s review)
404Not FoundResource doesn’t exist, invalid route
409ConflictDuplicate resource (e.g., reviewing the same route twice)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error Types

1. Custom Application Errors

The API defines custom error classes for specific scenarios:
// 401 Unauthorized
{
  "success": false,
  "error": "No authentication token provided"
}
// 403 Forbidden
{
  "success": false,
  "error": "You don't have permission to edit this review"
}
// 404 Not Found
{
  "success": false,
  "error": "Route not found"
}
// 409 Conflict
{
  "success": false,
  "error": "You have already reviewed this route"
}
Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:18

2. Validation Errors (Zod)

When request data fails validation, the API returns detailed field-level errors:
{
  "success": false,
  "error": "Validation Error",
  "details": [
    {
      "field": "rating",
      "message": "Rating must be between 1 and 5"
    },
    {
      "field": "comment",
      "message": "Comment must be at least 10 characters"
    }
  ]
}
Status Code: 400 Bad Request Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:27

3. Database Errors (Prisma)

The API handles common database errors gracefully:

Unique Constraint Violation (P2002)

{
  "success": false,
  "error": "A record with this value already exists",
  "field": ["email"]
}
Status Code: 409 Conflict Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:41

Record Not Found (P2025)

{
  "success": false,
  "error": "Record not found"
}
Status Code: 404 Not Found Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:50

Foreign Key Constraint (P2003)

{
  "success": false,
  "error": "Invalid reference to related record",
  "field": "userId"
}
Status Code: 400 Bad Request Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:58

Invalid Data Format

{
  "success": false,
  "error": "Invalid data format"
}
Status Code: 400 Bad Request Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:68

4. Route Not Found (404)

When accessing a non-existent endpoint:
{
  "success": false,
  "error": "Route not found",
  "path": "/api/invalid-endpoint"
}
Status Code: 404 Not Found Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:91

5. Internal Server Error (500)

For unexpected errors, the API returns a generic error message:
{
  "success": false,
  "error": "Internal Server Error"
}
In development mode, additional debug information is included:
{
  "success": false,
  "error": "Internal Server Error",
  "details": "Detailed error message",
  "stack": "Error stack trace..."
}
Status Code: 500 Internal Server Error Location: /home/daytona/workspace/source/src/shared/middlewares/error.middleware.ts:76
Stack traces and detailed error messages are only included in development mode for security reasons.

Error Handling Examples

JavaScript/TypeScript

try {
  const response = await fetch('/api/routes/ruta-1/reviews', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      rating: 5,
      comment: 'Great route!'
    })
  });

  const data = await response.json();

  if (!data.success) {
    // Handle error
    if (response.status === 409) {
      console.error('You already reviewed this route');
    } else if (response.status === 401) {
      console.error('Please log in to review');
    } else {
      console.error(data.error);
    }
    return;
  }

  // Success
  console.log('Review created:', data.data);
} catch (error) {
  console.error('Network error:', error);
}

Handling Validation Errors

const response = await fetch('/api/routes/ruta-1/reviews', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ rating: 6 }) // Invalid rating
});

const data = await response.json();

if (response.status === 400 && data.details) {
  // Show field-specific errors
  data.details.forEach(error => {
    console.error(`${error.field}: ${error.message}`);
    // Display error next to the form field
  });
}

Best Practices

  1. Always check the success field in responses to determine if the request succeeded
  2. Use HTTP status codes to determine the appropriate error handling strategy
  3. Display validation errors next to the relevant form fields for better UX
  4. Handle authentication errors by redirecting to login or refreshing tokens
  5. Log unexpected 500 errors and provide a user-friendly message
  6. Don’t expose sensitive information in production error messages

Build docs developers (and LLMs) love