Argus.Extractors.ErrorHandling (Panoptes v0.13.0)

Copy Markdown View Source

Error handling extractor.

Detects error handling patterns and anti-patterns in BEAM bytecode: bare rescues (catch-all without filtering or reraising), trap_exit without handlers, explicit exit calls, and ignored error results.

Approach

For bare rescue detection, walks forward from try_start handler labels. If the handler code contains no test/select_val filtering exception class and no :erlang.raise/3 call, it's a bare rescue that silently swallows exceptions.

Emitted facts

  • bare_rescue(id, func) — catch-all rescue without filtering or reraising
  • trap_exit(func, mod)Process.flag(:trap_exit, true) call site
  • exit_call(id, func, target) — explicit Process.exit/2 or :erlang.exit/1,2
  • ignored_error_result(id, func, callee) — call to known ok/error API where result is not pattern matched
  • catch_total(id, func, class) — some clause catches class without a pattern on the reason
  • catch_tag(id, func, class, tag) — an atom a clause catching class compares against (its reason pattern, or a case in its body); rescue X yields the struct name X
  • catch_falls_through(id, func, tag) — a case inside the handler, reached after comparing tag, has no clause for some value, so an unexpected reason is a CaseClauseError
  • try_call(id, func, callee) — a peer call (GenServer.call, :gen_statem.call, :erpc.call, ...) the try at id guards
  • mailbox_writer(id, func, kind) — a call after which something other than a peer's request lands in this process's mailbox: task (a Task.async reply), timer (send_after / send_interval), pubsub (a subscription), self (the function sends to self()), apply (the function runs a caller-supplied function, which may do anything with this mailbox — the Flow producer of gen_stage#238 ran user code that called hackney)