Files
Emailsorter/server/middleware/errorHandler.mjs
ANDJ abf761db07 Email Sorter Beta
Ich habe soweit automatisiert the Emails sortieren aber ich muss noch schauen was es fur bugs es gibt wenn die app online  ist deswegen wurde ich mit diesen Commit die website veroffentlichen obwohjl es sein konnte  das es noch nicht fertig ist und verkaufs bereit
2026-01-22 19:32:12 +01:00

107 lines
2.6 KiB
JavaScript

/**
* Global Error Handler Middleware
* Catches all errors and returns consistent JSON responses
*/
export class AppError extends Error {
constructor(message, statusCode = 500, code = 'INTERNAL_ERROR') {
super(message)
this.statusCode = statusCode
this.code = code
this.isOperational = true
Error.captureStackTrace(this, this.constructor)
}
}
export class ValidationError extends AppError {
constructor(message, fields = {}) {
super(message, 400, 'VALIDATION_ERROR')
this.fields = fields
}
}
export class AuthenticationError extends AppError {
constructor(message = 'Nicht authentifiziert') {
super(message, 401, 'AUTHENTICATION_ERROR')
}
}
export class AuthorizationError extends AppError {
constructor(message = 'Keine Berechtigung') {
super(message, 403, 'AUTHORIZATION_ERROR')
}
}
export class NotFoundError extends AppError {
constructor(resource = 'Ressource') {
super(`${resource} nicht gefunden`, 404, 'NOT_FOUND')
}
}
export class RateLimitError extends AppError {
constructor(message = 'Zu viele Anfragen') {
super(message, 429, 'RATE_LIMIT_EXCEEDED')
}
}
/**
* Error handler middleware
*/
export function errorHandler(err, req, res, next) {
// Log error
console.error(`[ERROR] ${new Date().toISOString()}`, {
method: req.method,
path: req.path,
error: err.message,
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
})
// Default error values
let statusCode = err.statusCode || 500
let code = err.code || 'INTERNAL_ERROR'
let message = err.message || 'Ein Fehler ist aufgetreten'
// Handle specific error types
if (err.name === 'ValidationError') {
statusCode = 400
code = 'VALIDATION_ERROR'
}
if (err.name === 'JsonWebTokenError') {
statusCode = 401
code = 'INVALID_TOKEN'
message = 'Ungültiger Token'
}
if (err.name === 'TokenExpiredError') {
statusCode = 401
code = 'TOKEN_EXPIRED'
message = 'Token abgelaufen'
}
// Don't expose internal errors in production
if (!err.isOperational && process.env.NODE_ENV === 'production') {
message = 'Ein interner Fehler ist aufgetreten'
}
// Send response
res.status(statusCode).json({
success: false,
error: {
code,
message,
...(err.fields && { fields: err.fields }),
...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
},
})
}
/**
* Async handler wrapper to catch errors in async routes
*/
export function asyncHandler(fn) {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next)
}
}