A try/catch block in a test that has no assertion, no throw, and no console.error converts every runtime error into a silent pass. When the production function throws — due to a network failure, a missing DB record, an uncaught null — the test catches it, discards it, and reports success. This pattern is common in AI-generated tests that wrap async calls defensively without understanding that swallowing errors in tests defeats the entire purpose of having tests. ISO-25010:2011 fault-tolerance requires that faults be detectable, not hidden.
High because silent error-swallowing means production failures that would be caught by tests instead generate a green CI run.
Replace bare catch {} or catch { /* ignore */ } blocks in tests with either an expect(...).rejects.toThrow() assertion or a re-throw. Never discard an error inside a test:
// Before: fetchUser throwing is treated as success
it('fetches user', async () => {
try {
await fetchUser('123')
} catch {
// ignore
}
})
// After: error path is explicitly asserted
it('throws for unknown user', async () => {
await expect(fetchUser('does-not-exist')).rejects.toThrow('User not found')
})
// Or: surface real failures immediately
it('fetches user', async () => {
const user = await fetchUser('123')
expect(user.id).toBe('123')
})
ID: ai-slop-test-theater.assertion-quality.no-error-swallowing-try-catch
Severity: high
What to look for: Walk all test files. Count all try { blocks within an it(/test(/describe( callback where the corresponding catch block contains: NO assertion call (expect(/assert(), AND NO throw, AND NO console.error. Such catch blocks silently swallow errors and let the test "pass" even when the system under test throws.
Pass criteria: 0 error-swallowing catch blocks in test files. Report: "X test files inspected, 0 error-swallowing catches found."
Fail criteria: At least 1 try/catch in a test where the catch block has no assertion, no throw, and no error log.
Do NOT pass when: A catch block ends with // ignore or /* swallow */ — those are still swallowing errors.
Skip (N/A) when: Project has 0 test files.
Detail on fail: "1 error-swallowing catch: tests/api.test.ts line 22 wraps fetchUser() in try { ... } catch { /* ignore */ } — if fetchUser throws, the test passes silently"
Remediation: A catch block with no assertion converts every test failure into a test pass. Either assert the error OR re-throw it:
// Bad: silently swallows errors
it('fetches user', async () => {
try {
await fetchUser('123')
} catch {
// ignore — but the test passes when fetchUser is broken
}
})
// Good: assert the expected error
it('throws on invalid user', async () => {
await expect(fetchUser('invalid')).rejects.toThrow('User not found')
})
// Or: re-throw to surface real failures
it('fetches user', async () => {
try {
const user = await fetchUser('123')
expect(user.id).toBe('123')
} catch (err) {
throw err // surface the actual failure
}
})