Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing the message of a structured diagnostic #189

Open
mikeshulman opened this issue Nov 23, 2024 · 2 comments
Open

Changing the message of a structured diagnostic #189

mikeshulman opened this issue Nov 23, 2024 · 2 comments

Comments

@mikeshulman
Copy link
Collaborator

Suppose I'm using StructuredReporter and I want to catch a fatal error, change the message code, and re-raise it. I would naively expect the following to work:

Reporter.try_with (fun () -> fatal Original_message)
  ~fatal:(fun d -> fatal_diagnostic { d with message = New_message })

However, this doesn't work, because the original call to fatal has already invoked get_text on Original_message and stored the result in d.explanation, and that's what gets displayed to the user. This is unintuitive to me and was hard to track down.

I feel like in general if an interface includes the definition of a type as a record, then it should be valid to define new elements of that type as records. If there are invariants that should be maintained relating the fields, or if some fields are memoized computations from other fields, then the fact that the type is a record shouldn't be exposed in the interface. Of course a change like that would be breaking. A partial solution would be to supply a function like with_message that changes the message and also recomputes the explanation:

let with_message { severity; message = _; backtrace; explanation; extra_remarks } message = 
  let explanation = locate_opt explanation.loc (Code.default_text message) in
  { severity; message; backtrace; explanation; extra_remarks }

With a warning in the documentation that this should be used instead of manually setting the message field.

@favonia
Copy link
Contributor

favonia commented Dec 12, 2024

As we are breaking the interface with #184, maybe we should indeed hide the record type from the interface. And maybe the helper function could be map_message that takes the old message. Maybe the map_message should take an optional argument for keeping thee current explanation.

@mikeshulman
Copy link
Collaborator Author

Sounds good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants