Skip to content

Commit 5306218

Browse files
authored
Add [Needs_stack_trace] annotation for user errors (#5047)
In #5025 that introduces directory targets, I need a way to force a user error to include the stack trace even though it has an embedded location. This PR makes this possible via the new [Needs_stack_trace] annotation. I also fix a naming inconsistency and rename [has_embed_location] to [has_embedded_location]. Signed-off-by: Andrey Mokhov <[email protected]>
1 parent d178570 commit 5306218

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

otherlibs/stdune-unstable/user_error.ml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ module Annot = struct
4040

4141
let to_dyn = Unit.to_dyn
4242
end)
43+
44+
module Needs_stack_trace = Make (struct
45+
type payload = unit
46+
47+
let to_dyn = Unit.to_dyn
48+
end)
4349
end
4450

4551
exception E of User_message.t * Annot.t list
@@ -58,12 +64,16 @@ let is_loc_none loc =
5864
| None -> true
5965
| Some loc -> loc = Loc0.none
6066

61-
let has_embed_location annots =
67+
let has_embedded_location annots =
6268
List.exists annots ~f:(fun annot ->
6369
Annot.Has_embedded_location.check annot (fun () -> true) (fun () -> false))
6470

6571
let has_location (msg : User_message.t) annots =
66-
(not (is_loc_none msg.loc)) || has_embed_location annots
72+
(not (is_loc_none msg.loc)) || has_embedded_location annots
73+
74+
let needs_stack_trace annots =
75+
List.exists annots ~f:(fun annot ->
76+
Annot.Needs_stack_trace.check annot (fun () -> true) (fun () -> false))
6777

6878
let () =
6979
Printexc.register_printer (function

otherlibs/stdune-unstable/user_error.mli

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ module Annot : sig
1919

2020
(** The message has a location embed in the text. *)
2121
module Has_embedded_location : S with type payload = unit
22+
23+
(** The message needs a stack trace for clarity. *)
24+
module Needs_stack_trace : S with type payload = unit
2225
end
2326

2427
(** User errors are errors that users need to fix themselves in order to make
@@ -48,10 +51,12 @@ val make :
4851
(** The "Error:" prefix *)
4952
val prefix : User_message.Style.t Pp.t
5053

51-
(** Returns [true] if the message has an explicit location or one embed in the
52-
text. *)
54+
(** Returns [true] if the message has an explicit location or one embedded in
55+
the text. *)
5356
val has_location : User_message.t -> Annot.t list -> bool
5457

55-
(** Returns [true] if the following list of annotations contains
56-
[Annot.Has_embedded_location]. *)
57-
val has_embed_location : Annot.t list -> bool
58+
(** Returns [true] if the list contains [Annot.Has_embedded_location]. *)
59+
val has_embedded_location : Annot.t list -> bool
60+
61+
(** Returns [true] if the list contains [Annot.Needs_stack_trace]. *)
62+
val needs_stack_trace : Annot.t list -> bool

src/dune_util/report_error.ml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type error =
1010
{ responsible : who_is_responsible_for_the_error
1111
; msg : User_message.t
1212
; has_embedded_location : bool
13+
; needs_stack_trace : bool
1314
}
1415

1516
let code_error ~loc ~dyn_without_loc =
@@ -25,6 +26,7 @@ let code_error ~loc ~dyn_without_loc =
2526
; Pp.box ~indent:2 (Pp.verbatim " " ++ Dyn.pp dyn_without_loc)
2627
]
2728
; has_embedded_location = false
29+
; needs_stack_trace = false
2830
}
2931

3032
let get_error_from_exn = function
@@ -59,10 +61,12 @@ let get_error_from_exn = function
5961
; Pp.chain cycle ~f:(fun p -> p)
6062
]
6163
; has_embedded_location = false
64+
; needs_stack_trace = false
6265
})
6366
| User_error.E (msg, annots) ->
64-
let has_embedded_location = User_error.has_embed_location annots in
65-
{ responsible = User; msg; has_embedded_location }
67+
let has_embedded_location = User_error.has_embedded_location annots in
68+
let needs_stack_trace = User_error.needs_stack_trace annots in
69+
{ responsible = User; msg; has_embedded_location; needs_stack_trace }
6670
| Code_error.E e ->
6771
code_error ~loc:e.loc ~dyn_without_loc:(Code_error.to_dyn_without_loc e)
6872
| Unix.Unix_error (err, func, fname) ->
@@ -71,11 +75,13 @@ let get_error_from_exn = function
7175
User_error.make
7276
[ Pp.textf "%s: %s: %s" func fname (Unix.error_message err) ]
7377
; has_embedded_location = false
78+
; needs_stack_trace = false
7479
}
7580
| Sys_error msg ->
7681
{ responsible = User
7782
; msg = User_error.make [ Pp.text msg ]
7883
; has_embedded_location = false
84+
; needs_stack_trace = false
7985
}
8086
| exn ->
8187
let open Pp.O in
@@ -96,6 +102,7 @@ let get_error_from_exn = function
96102
{ responsible = Developer
97103
; msg = User_message.make ?loc [ pp ]
98104
; has_embedded_location = Option.is_some loc
105+
; needs_stack_trace = false
99106
}
100107

101108
let i_must_not_crash =
@@ -143,7 +150,9 @@ let report { Exn_with_backtrace.exn; backtrace } =
143150
match exn with
144151
| Already_reported -> ()
145152
| _ ->
146-
let { responsible; msg; has_embedded_location } = get_error_from_exn exn in
153+
let { responsible; msg; has_embedded_location; needs_stack_trace } =
154+
get_error_from_exn exn
155+
in
147156
let msg =
148157
if msg.loc = Some Loc.none then
149158
{ msg with loc = None }
@@ -163,7 +172,7 @@ let report { Exn_with_backtrace.exn; backtrace } =
163172
~f:(fun line -> Pp.box ~indent:2 (Pp.text line)))
164173
in
165174
let memo_stack =
166-
if !print_memo_stacks then
175+
if !print_memo_stacks || needs_stack_trace then
167176
memo_stack
168177
else
169178
match msg.loc with

0 commit comments

Comments
 (0)