ocaml.lang.best-practice.exception.bad-reraise

Author
unknown
Download Count*
License
You should not re-raise exceptions using 'raise' because it loses track of where the exception was raised originally, leading to a useless and possibly confusing stack trace. Instead, you should obtain a stack backtrace as soon as the exception is caught using 'try ... with exn -> let trace = Printexc.get_raw_backtrace () in ...', and keep it around until you re-raise the exception using 'Printexc.raise_with_backtrace exn trace'. You must collect the stack backtrace before calling another function which might internally raise and catch exceptions. To avoid false positives from Semgrep, write 'raise (Foo args)' instead of 'let e = Foo args in raise e'.
Run Locally
Run in CI
Defintion
rules:
- id: bad-reraise
patterns:
- pattern: |
raise $EXN
- metavariable-regex:
metavariable: $EXN
regex: \A[a-z_][a-z_A-Z0-9']*\z
message: You should not re-raise exceptions using 'raise' because it loses track
of where the exception was raised originally, leading to a useless and
possibly confusing stack trace. Instead, you should obtain a stack
backtrace as soon as the exception is caught using 'try ... with exn ->
let trace = Printexc.get_raw_backtrace () in ...', and keep it around
until you re-raise the exception using 'Printexc.raise_with_backtrace exn
trace'. You must collect the stack backtrace before calling another
function which might internally raise and catch exceptions. To avoid false
positives from Semgrep, write 'raise (Foo args)' instead of 'let e = Foo
args in raise e'.
languages:
- ocaml
severity: WARNING
metadata:
category: best-practice
technology:
- ocaml
references:
- https://v2.ocaml.org/api/Printexc.html
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
Examples
exception.ml
let () =
try ()
with exn ->
(* ruleid:bad-reraise *)
raise exn
let () =
match () with
| Foo _ ->
raise Not_found
| _ as _exn2' ->
(* ruleid:bad-reraise *)
raise _exn2'
let () =
raise (Error "uh oh")
let () =
raise Exit
(* false positive *)
let () =
let e = Foo args in
(* ruleid:bad-reraise *)
raise e
(* no longer a false positive *)
let () =
raise (Foo args)
Short Link: https://sg.run/5ewK