diff --git a/eeps/eep-0072-1.png b/eeps/eep-0072-1.png new file mode 100644 index 0000000..2584e2d Binary files /dev/null and b/eeps/eep-0072-1.png differ diff --git a/eeps/eep-0072.md b/eeps/eep-0072.md new file mode 100644 index 0000000..1fae711 --- /dev/null +++ b/eeps/eep-0072.md @@ -0,0 +1,195 @@ + Author: Roberto Aloi + Status: Draft + Type: Standards Track + Created: 23-Aug-2024 + Erlang-Version: OTP-28 + Post-History: +**** +EEP 72: Erlang Error Index +---- + +Abstract +======== + +The **Erlang Error Index** is a _catalogue_ of errors emitted by +various tools within the Erlang ecosystem, including - but not limited +to - the `erlc` Erlang compiler and the `dialyzer` type checker. + +The catalogue is not limited to tools shipped with Erlang/OTP, but it +can include third-party applications such as the [EqWAlizer][] +type-checker or the [Elvis][] code style reviewer. + +Each error in the catalogue is identified by a **unique code** and it +is accompanied by a description, examples and possible courses of +action. Error codes are _namespaced_ based on the tool that generates +them. + +Unique error codes can be leveraged by IDEs and language servers to +provide better contextual information about errors and make errors +easier to search and reference. A standardized error index creates a +common space for the Community to provide extra examples and +documentation, creating the perfect companion for the Erlang User +Manual and standard documentation. + +Rationale +========= + +The concept of an "Error Index" for a programming language is not a +novel idea. Error catalogues already exist, for example, in the +[Rust][] and [Haskell][] Communities. + +Producing meaningful error messages can sometimes be challenging for +developer tools such as compilers and type checkers due to various +constraints, including limited context and character count. + +By associating a **unique code** to each _diagnostic_ (warning or +error) we relief tools from having to condense a lot of textual +information into a - sometime cryptic - generic, single +sentence. Furthermore, as specific wording of errors and warnings is +improved over time, error codes remain constant, providing a +search-engine friendly way to index and reference diagnostics. + +An good example of this is the _expression updates a literal_ error +message, introduced in OTP 27. Given the following code: + + -define(DEFAULT, #{a => 1}). + + updated(Value) -> + ?DEFAULT#{a => Value}. + +The compiler emits the following error: + + test.erl:8:11: Warning: expression updates a literal + % 8| ?DEFAULT#{timeout => 1000}. + % | ^ + +The meaning of the error may not be obvious to everyone. Most +importantly, the compiler provide no information on why the warning is +raised and what a user could do about it. The user will then have to +recur to a search engine, a forum or equivalent to proceed. + +Conversely, we can associate a unique identifier to the code (say, +`ERL-1234`): + + test.erl:8:11: Warning: expression updates a literal (ERL-1234) + % 8| ?DEFAULT#{timeout => 1000}. + % | ^ + +The code make it possible to link the error message to an external +resource (a wiki), which contains all the required, additional, +information about the error that would not be practical to present +directly to the user. Here is an example of what the entry could look +like for the above code: + +![Erlang Error Index Sample Entry][] + +Unique error codes also have the advantage to be better searchable in +forums and chats, where the exact error message could vary, but the +error code would be the same. + +Finally, error codes can be used by IDEs (e.g. via language servers) +to match on error codes and provide contextual help. Both the [Erlang +LS][] and the [ELP][] language server already use "unofficial" error +codes. + +Format +------ + +An error code should be composed by two parts: an alphanumeric +_namespace_ (three letters) and a numeric identifier (four digits), +divided by a dash (`-`). + +A potential set of namespaces could look like the following: + +| Namespace | Description | +|-----------|----------------------------------------------------------------| +| ERL | The Erlang compiler and related tools (linter, parser, scanner | +| DIA | The Dialyzer type-checker | +| ELV | The Elvis code-style reviewer | +| ELP | The Erlang Language Platform | +| ... | ... | + +A set of potential error codes could look like: + + ERL-0123 + DIA-0009 + ELV-0015 + ELP-0001 + +The exact number of characters/digits for each namespace and code is +open for discussion, as well as the fact whether components such as +the parser, the scanner or the `erlint` Erlang linter should have +their own namespace. + +Responsibilities +---------------- + +The Erlang/OTP team would be ultimately responsible for maintaining a + list of _official_ namespaces. Each tool maintainer would then be + responsible to allocate specific codes to specific diagnostics. + +Processes +--------- + +Error cannot be re-used. If a tool stops emitting an error code, the +_deprecated_ error code is still documented in the index, together +with a deprecation notice. This is to avoid re-using a single code for +multiple purposes. + +Reference Implementation +------------------------ + +The [ELP website][] contains a proof of concept of what an Erlang +Error Index could look like. Ideally, such a website would live under +the `erlang.org` domain. + +The website should use _Markdown_ as the primary mechanism to write +content and it should be easily extensible by the Community. + +Required Changes +================ + +* The `erlc` compiler and the `dialyzer` type-checker would start + emitting error codes together with errors and warnings messags. +* The tools could also expose a `--explain` option from the command + line - similarly to `rustc` - which would take an error code as the + input and return the Markdown documentation as output. + +Copyright +========= + +This document is placed in the public domain or under the CC0-1.0-Universal +license, whichever is more permissive. + +[EqWAlizer]: https://github.com/whatsapp/eqwalizer + "The EqWAlizer Type Checker" + +[Elvis]: https://github.com/inaka/elvis + "The Elvis Style Reviewer" + +[Rust]: https://doc.rust-lang.org/error_codes/error-index.html + "The Rust Error Index" + +[Haskell]: https://errors.haskell.org + "The Haskell Error Index" + +[Erlang Error Index Sample Entry]: eep-0072-1.png + "Erlang Error Index Sample Entry" + +[Erlang LS]: https://github.com/erlang-ls/erlang_ls/blob/a4a12001e36b26343d1e9d57a0de0526d90480f2/apps/els_lsp/src/els_compiler_diagnostics.erl#L237 + "Erlang LS using error codes" + +[ELP]: https://github.com/WhatsApp/erlang-language-platform/blob/99a426772be274f3739116736bb22d4c98c123c4/erlang_service/src/erlang_service.erl#L608 + "ELP using error codes" + +[ELP Website]: https://whatsapp.github.io/erlang-language-platform/docs/erlang-error-index/ + "ELP website" + +[EmacsVar]: <> "Local Variables:" +[EmacsVar]: <> "mode: indented-text" +[EmacsVar]: <> "indent-tabs-mode: nil" +[EmacsVar]: <> "sentence-end-double-space: t" +[EmacsVar]: <> "fill-column: 70" +[EmacsVar]: <> "coding: utf-8" +[EmacsVar]: <> "End:" +[VimVar]: <> " vim: set fileencoding=utf-8 expandtab shiftwidth=4 softtabstop=4: "