Page
Library
Module
Module type
Parameter
Class
Class type
Source
Reporter.MakeSourceThe functor to generate a reporter.
val emit :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
Message.t ->
string ->
unitemit message explanation emits the explanation and continues the computation.
Example:
Reporter.emit TypeError "the type `nat' is extremely unnatural"val emitf :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
Message.t ->
('a, Format.formatter, unit, unit) format4 ->
'aemitf message format ... formats and emits a message, and then continues the computation. Note that there should not be any literal control characters. See Diagnostic.text.
Example:
Reporter.emitf TypeError "type %a is too ugly" Syntax.pp tpEmit a diagnostic and continue the computation.
val fatal :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
Message.t ->
string ->
'afatal message explanation aborts the current computation with the explanation.
Example:
Reporter.fatal CatError "forgot to feed the cat"val fatalf :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
Message.t ->
('a, Format.formatter, unit, 'b) format4 ->
'afatalf message format ... constructs a diagnostic and aborts the current computation with the diagnostic. Note that there should not be any literal control characters. See Diagnostic.text.
Example:
Reporter.fatalf SecurityTooStrict "failed to write the password %s on the screen" passwordAbort the computation with a diagnostic.
get_backtrace() returns the current backtrace.
with_backtrace bt f runs the thunk f with bt as the initial backtrace.
Example:
(* running code with a fresh backtrace *)
with_backtrace Emp @@ fun () -> ...trace str f records the string str and runs the thunk f with the new backtrace.
tracef format ... f formats and records a frame in the backtrace, and runs the thunk f with the new backtrace. Note that there should not be any literal control characters. See Diagnostic.text.
trace_text text f records the text and runs the thunk f with the new backtrace.
merge_loc loc f "merges" loc into the current default location for emit and fatal and runs the thunk f. By "merge", it means that if loc is None, then the current default location is kept; otherwise, it is overwritten. Note that with_loc None will clear the current default location, while merge_loc None will keep it. See with_loc.
Functions in this section differ from the ones in Diagnostic (for example, Diagnostic.make) in that they fill out the current location, the current backtrace, and the severity automatically. (One can still overwrite them with optional arguments.)
val diagnostic :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
Message.t ->
string ->
Message.t Diagnostic.tdiagnostic message explanation constructs a diagnostic with the explanation along with the backtrace frames recorded via trace.
Example:
Reporter.diagnostic SyntaxError "too many emojis"val diagnosticf :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
Message.t ->
('a, Format.formatter, unit, Message.t Diagnostic.t) format4 ->
'adiagnosticf message format ... constructs a diagnostic along with the backtrace frames recorded via trace. Note that there should not be any literal control characters. See Diagnostic.text.
Example:
Reporter.diagnosticf TypeError "term %a does not type check, maybe" Syntax.pp tmval kdiagnosticf :
?severity:Diagnostic.severity ->
?loc:Range.t ->
?backtrace:Diagnostic.backtrace ->
?extra_remarks:Diagnostic.loctext list ->
(Message.t Diagnostic.t -> 'b) ->
Message.t ->
('a, Format.formatter, unit, 'b) format4 ->
'akdiagnosticf kont message format ... is kont (diagnosticf message format ...). Note that there should not be any literal control characters. See Diagnostic.text.
val run :
?init_loc:Range.t ->
?init_backtrace:Diagnostic.backtrace ->
emit:(Message.t Diagnostic.t -> unit) ->
fatal:(Message.t Diagnostic.t -> 'a) ->
(unit -> 'a) ->
'aval adopt :
('message Diagnostic.t -> Message.t Diagnostic.t) ->
(?init_loc:Range.t ->
?init_backtrace:Diagnostic.backtrace ->
emit:('message Diagnostic.t -> unit) ->
fatal:('message Diagnostic.t -> 'a) ->
(unit -> 'a) ->
'a) ->
(unit -> 'a) ->
'aadopt m run f runs the thunk f that uses a different Reporter instance. It takes the runner run from that Reporter instance as an argument to handle effects, and will use m to transform diagnostics generated by f into ones in the current Reporter instance. The backtrace within f will include the backtrace that leads to adopt, and the innermost specified location will be carried over, too. The intended use case is to integrate diagnostics from a library into those in the main application.
adopt is a convenience function that can be implemented as follows:
let adopt m f run =
run
?init_loc:(get_loc())
?init_backtrace:(Some (get_backtrace()))
~emit:(fun d -> emit_diagnostic (m d))
~fatal:(fun d -> fatal_diagnostic (m d))
fHere shows the intended usage, where Cool_lib is the library to be used in the main application:
Reporter.adopt (Diagnostic.map message_mapper) Cool_lib.Reporter.run @@ fun () -> ...val try_with :
?emit:(Message.t Diagnostic.t -> unit) ->
?fatal:(Message.t Diagnostic.t -> 'a) ->
(unit -> 'a) ->
'amap_diagnostic m f runs the thunk f and applies m to any diagnostic sent by f. It is a convenience function that can be implemented as follows:
let map_diagnostic m f =
try_with
~fatal:(fun d -> fatal_diagnostic (m d))
~emit:(fun d -> emit_diagnostic (m d))
fval register_printer :
([ `Trace
| `Emit of Message.t Diagnostic.t
| `Fatal of Message.t Diagnostic.t ] ->
string option) ->
unitregister_printer p registers a printer p via Printexc.register_printer to convert unhandled internal effects and exceptions into strings for the OCaml runtime system to display. Ideally, all internal effects and exceptions should have been handled by run and there is no need to use this function, but when it is not the case, this function can be helpful for debugging. The functor Reporter.Make always registers a simple printer to suggest using run, but you can register new ones to override it. The return type of the printer p should return Some s where s is the resulting string, or None if it chooses not to convert a particular effect or exception. The registered printers are tried in reverse order until one of them returns Some s for some s; that is, the last registered printer is tried first. Note that this function is a wrapper of Printexc.register_printer and all the registered printers (via this function or Printexc.register_printer) are put into the same list.
The input type of the printer p is a variant representation of all internal effects and exceptions used in this module:
`Trace corresponds to the effect triggered by trace; and`Emit diag corresponds to the effect triggered by emit; and`Fatal diag corresponds to the exception triggered by fatal.Note: Diagnostic.string_of_text can be handy for converting a text into a string.