Aller au contenu

Gestion des erreurs

Lacis exporte des constructeurs d’erreurs HTTP typés et un helper sendError. Utilisez-les pour envoyer des réponses d’erreur cohérentes et correctement formatées sans écrire res.status(...).json(...) manuellement.

import {
createBadRequestError, // 400
createUnauthorizedError, // 401
createForbiddenError, // 403
createNotFoundError, // 404
createConflictError, // 409
createValidationError, // 422
createInternalServerError, // 500
createServiceUnavailableError, // 503
createGatewayTimeoutError, // 504
} from 'lacis'

Chacun accepte un message optionnel et un objet details :

createNotFoundError('Utilisateur non trouvé', { id: req.params.id })

Le pattern le plus simple : throw n’importe quel constructeur d’erreur et Lacis envoie automatiquement le bon code de statut.

import type { Request, Response } from 'lacis'
import { createUnauthorizedError, createNotFoundError } from 'lacis'
export async function GET(req: Request, res: Response) {
const token = req.getHeader('authorization')
if (!token) throw createUnauthorizedError('Token manquant')
const user = await db.findUser(req.params.id)
if (!user) throw createNotFoundError('Utilisateur non trouvé', { id: req.params.id })
res.json(user)
}

Alternative au throw — envoie l’erreur en JSON et définit le bon code de statut directement. Utile quand vous devez envoyer une erreur et faire du nettoyage avant de retourner.

import type { Request, Response } from 'lacis'
import { sendError, createUnauthorizedError, createNotFoundError } from 'lacis'
export async function GET(req: Request, res: Response) {
const token = req.getHeader('authorization')
if (!token) {
sendError(createUnauthorizedError('Token manquant'), res)
return
}
const user = await db.findUser(req.params.id)
if (!user) {
sendError(createNotFoundError('Utilisateur non trouvé', { id: req.params.id }), res)
return
}
res.json(user)
}

Le client reçoit :

{ "error": "Utilisateur non trouvé", "code": 404, "details": { "id": "42" } }
  • Erreurs 4xxdetails est inclus dans le corps de la réponse (sûr à exposer au client)
  • Erreurs 5xxdetails n’est jamais envoyé au client ; l’erreur est loguée côté serveur
// ✅ details envoyés au client — 422
sendError(createValidationError('Entrée invalide', { field: 'email' }), res)
// → { "error": "Entrée invalide", "code": 422, "details": { "field": "email" } }
// ✅ details NON envoyés au client — 500
sendError(createInternalServerError('Requête DB échouée', { query: sql }), res)
// → { "error": "Internal Server Error", "code": 500 }

Utilisez le hook middleware onError pour centraliser les logs ou transmettre les erreurs à un service externe :

import { createServer, normalizeError, sendError } from 'lacis'
createServer('./routes', {
middleware: {
onError: async (req, res, ctx) => {
const error = normalizeError(ctx.error)
// Transmettre à Sentry, Datadog, etc.
captureException(error)
if (!res.headersSent) {
sendError(error, res)
}
},
},
})

Convertit n’importe quelle erreur inconnue en HttpError typé. Utile dans onError quand vous ne contrôlez pas la source de l’erreur :

import { normalizeError } from 'lacis'
const error = normalizeError(unknownErr)
// ECONNREFUSED / ENOTFOUND → 503
// ETIMEDOUT → 504
// { statusCode: 422 } → 422
// tout le reste → 500