Skip to content

Error Handling Antipatterns

Error handling antipatterns make applications unreliable and hard to debug. They can also expose sensitive information to attackers.

Catching exceptions and ignoring them completely.

Showing stack traces and implementation details to users.

Catching everything with the same handler.



AntipatternProblemSolution
Error SwallowingSilent failuresLog and rethrow
Error ExposureInformation leakageSanitized responses
Generic CatchLost contextTyped error handling

// Bad - silent failure
try {
await saveData(data)
} catch (e) {
// ignore
}
// Good - fail visibly
try {
await saveData(data)
} catch (error) {
logger.error('Failed to save data', { error, data })
throw new DataPersistenceError('Save failed', { cause: error })
}
// Internal: full details for logging
logger.error('Database connection failed', {
host: config.db.host,
error: error.message,
stack: error.stack,
})
// External: safe message for users
res.json({
error: 'Unable to process request',
code: 'SERVICE_UNAVAILABLE',
})
class ValidationError extends Error {
constructor(field, message) {
super(message)
this.field = field
this.code = 'VALIDATION_ERROR'
}
}
class NotFoundError extends Error {
constructor(resource, id) {
super(`${resource} not found: ${id}`)
this.code = 'NOT_FOUND'
}
}