grace icon indicating copy to clipboard operation
grace copied to clipboard

Design for handling error codes

Open francoisthire opened this issue 1 year ago • 3 comments

IIUC, the rationale behind the current design for handling error code is to separate the rendering from the code generating the diagnostic.

Trying to use the library in a project, I realize that if there are multiple diagnostics but I want to use the rendering only at once place in my code, this is not convenient to use since I need to export multiple definitions and it may not compose that well if I have multiple definitions of error codes. In that case, they need to be wrapped.

Moreover, the library does not ensure the uniqueness of the representation of the error code.

Have you considered a design where the library exports a type code with some constructors. And it is the library that handles the rendering?

Probably the user must provide optionally a code and a number. Then it is the responsibility of each library to provide such a mapping from any error type the user's library is using instead of doing this mapping by the renderer. This way, we recover some locality property.

If the library maintains some global state, it can also check where a code is not registered twice.

francoisthire avatar Jun 07 '24 16:06 francoisthire

By the way, at the moment, there is no way to opt-out from the error code (like for an Help message). Maybe code_to_string should return an option? Or the engine should handle the empty string in a particular way.

francoisthire avatar Jun 07 '24 17:06 francoisthire

Trying to use the library in a project, I realize that if there are multiple diagnostics but I want to use the rendering only at once place in my code, this is not convenient to use since I need to export multiple definitions and it may not compose that well if I have multiple definitions of error codes. In that case, they need to be wrapped.

The design of error codes was to be as agnostic as possible (hence why we parameterise the types and require a code_to_string function for rendering).

For your use-case, to avoid wrapping multiple definitions I suggest the following:

  • Polymorphic variants
  • Extensible variants
  • A single large closed variant for error codes (this is what rustc does)

Moreover, the library does not ensure the uniqueness of the representation of the error code.

It is up to the user to ensure injectivity of code_to_string for the existing design. I'll make this clearer in the documentation.

However, if you wish to keep the wrapped representation with a local code_to_string function for each code type, I suggest either:

  • Prefixing the individual codes when you wrap them. This would trivially give you injectivity for code_to_string.
  • Have some global hashtbl of codes, and check injectivity on registration of the mapping.

johnyob avatar Jun 18 '24 20:06 johnyob

By the way, at the moment, there is no way to opt-out from the error code (like for an Help message). Maybe code_to_string should return an option? Or the engine should handle the empty string in a particular way.

You should be able to opt-out of error codes by simply providing None for a code. For example:

open Grace

let diagnostic = Diagnostic.createf Help "help me"

johnyob avatar Jun 18 '24 20:06 johnyob

Closing as won't fix

johnyob avatar Aug 22 '25 11:08 johnyob