A catch block that contains only console.error() and no further action is functionally equivalent to swallowing the error in production. CWE-778 (Insufficient Logging) applies when logging goes only to a console that no one monitors in real time. CWE-391 (Unchecked Error Condition) applies when the error is recorded but not acted upon — no user feedback, no monitoring service capture. ISO 25010 reliability.fault-tolerance requires that error conditions trigger corrective action, not just log output. Most hosted Node.js environments (Vercel, Railway, Fly.io) don't surface raw console.error output to developers in real time, making bare-console error handling invisible in practice.
Low because `console.error`-only catch blocks produce a log record but no user feedback and no monitoring alert, making errors practically invisible in production hosting environments.
Replace bare console.error catch blocks with handling that notifies both the user and the monitoring service.
// Before — error disappears in production
} catch (error) {
console.error('Failed to fetch user:', error)
}
// After — error is visible to monitoring and the user
} catch (error) {
console.error('Failed to fetch user:', error) // keep for local dev context
Sentry.captureException(error, { extra: { context: 'fetchUser' } })
setError('Unable to load your profile. Please refresh.')
}
Search the codebase for console.error inside catch blocks using your IDE's symbol search and audit each one: if there is no captureException call and no state update in the same block, it needs both additions.
ID: saas-error-handling.graceful-degradation.no-console-error-without-boundary
Severity: low
What to look for: Search for console.error() calls throughout the codebase. For each one found: (1) Is it inside a catch block that also handles the error (shows UI, retries, reports to monitoring)? (2) Or is it a bare console.error() that logs the error but takes no further action — essentially swallowing the error after logging it? Look specifically for patterns where console.error is the only thing in a catch block, with no user-facing feedback, no error reporting service call, and no state update. These represent errors that are noticed by developers (who look at logs) but never surface to users or monitoring services.
Pass criteria: Count all console.error() calls in the codebase. Pass if console.error() calls are always accompanied by either: error reporting service capture, user-facing error state update, or both. No more than 0 unaccompanied console.error calls in production code. Report the count: "X console.error calls found, Y accompanied by error reporting."
Fail criteria: Fail if console.error() calls exist in catch blocks that take no further action (no user feedback, no monitoring service call). Do NOT pass when console.error is the sole error handling mechanism in any catch block — it is invisible to users and monitoring.
Skip (N/A) when: No console.error() calls exist in the codebase (the check passes trivially — no issues found).
Detail on fail: Count and describe the pattern (e.g., "7 catch blocks across API utilities and auth handlers use console.error() as sole error handling with no Sentry capture or user state update"). Max 500 chars.
Remediation: console.error() in production is a forest-falling-in-the-woods problem — the error happened, but no one will see it unless someone is actively tailing server logs. Most production environments don't expose raw logs to developers in real time.
Replace bare console.error calls with proper error handling:
// Before — error disappears in production
} catch (error) {
console.error('Failed to fetch user:', error)
}
// After — error is visible to both developer and monitoring
} catch (error) {
console.error('Failed to fetch user:', error) // keep for dev context
Sentry.captureException(error, { extra: { context: 'fetchUser' } })
setError('Unable to load your profile. Please refresh.')
}