IntentiAI

Error caught and silently discarded

An empty catch, except or rescue; an error assigned to _ in Go.

Check swallowed-errorsShip CheckJavaScript, TypeScript, Java, C#, Python, Go, Ruby

Why it matters

Wrapping a failing call in try with an empty catch is the fastest way to stop a stack trace, and agents use it when a call throws during their own test run. The code then runs to completion and the task looks finished.

When the call fails in production, the failure disappears. The request returns as if it worked, the user sees a success state built on nothing, and there is no error in the logs to find later. Bugs like this tend to be discovered from a customer report rather than from monitoring.

Example

 export async function saveSettings(userId: string, settings: Settings) {
-  await db.settings.upsert({ where: { userId }, create: settings, update: settings });
+  try {
+    await db.settings.upsert({ where: { userId }, create: settings, update: settings });
+  } catch (e) {
+  }
   return { ok: true };
 }

What it detects

  • New catch blocks whose body is empty or only pass, a bare return or null, including inline forms such as catch {} and .catch(() => {}), Python except: pass, and Ruby rescue with an empty body.
  • Go: if err != nil { } with an empty body, and errors assigned to the blank identifier _.
  • A catch that logs, rethrows or does anything else is not flagged. Neither is one with a comment inside it, directly above it, or above its try, since that comment is the explanation this check asks for.
  • Test files are skipped, and at most five findings are reported.

What to do when it fires

Handle the error or let it propagate. At minimum, log it with enough context to find later and return a failure to the caller instead of a success.

If ignoring it really is correct, for example best-effort telemetry, write a one-line comment in the catch saying why. The check treats that as a decision rather than a discard.

Error caught and silently discarded: AI code review check | IntentiAI