RFC-015: Error Handling #548
IWANABETHATGUY
started this conversation in
RFC
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Summary
High level design of rspack error handling.
Motivation
Instead of panicing when suffering an error, we want to display more human-readable diagnostics to users. This is for better user experience and developer debugging experience.
For the design of error handling, we want it to be:
Panic free (As much as possible), we don't panic when user gives a bad input. instead, we suggest users verify the configuration and the code they wrote.
Traceable (Let errors could be located quickly), referring to files that are not in the filesystem, see the different behavior of webpack and rspack:
Directory Tree
Webpack
Rspack
Categorizable (The diagnostic information is grouped into different categories to allow users and developers to quickly locate the location of the code in question):
For now we will probably classify them in two dimensions (more dimensions may be added in the future)
Severity
For example,
Error
,Warning
, etc. This allows user to customize the level of error displayed.Module
For example, different
plugins
andloaders
. This makes it easy for users to quickly locate where the error may have occurred.By combining these two dimensions we could also show only a certain level of error, making it easier for user to focus on solving a particular problem.
Guide-level explanation
Glossary
Diagnostic
An abstraction of the different levels of information,
Diagnostic
may be an error that cannot be recovered or may be a practice that is not recommended(for example:cycle dependency)Severity
Different levels of diagnosis e.g.
Error
,Warning
,Suggestion
.Progressive Error Handling Implementation
Result
instead. Adding a helper function for error emitting and display.Error (Message: String, start: usize, end: usize)
. and use the corresponding Error Reporter for error reporting.Rationale and alternatives
Based on research into rustc and webpack (see Prior art for details)
The principle is to use a
Context
that runs through the whole program, the core data provides theerrorEmit
function (using an array to carry all the error messages) that function mainly handles errors that don't crash the program, the rest of the errors are handled by the language-related error logic, e.g. (Webpack willthrow new Error
, rustc useResult
)We have two alternative implementations of this.
Implementation One
Similar to Webpack we also add an
errors
field toCompilation
After that, we need to change the signature of the call that takes
Compilation
as an argument toArc<Mutex<Compilation>>
Because potential errors can occur in any function call, for updating
Compilation.diagnostics
, we may need to add an extra argument to a lot of function calls.Cons
Mutex
.Implementation two
see #549,
Pros
Prior art
Webpack
webpack uses two different types of error handling, one for errors that are not recoverable or affect the execution of the program which uses throw new Error to interrupt the process. Another type of error that does not affect the execution of the build process directly pushes errors to Compilation.errors.
For the implementation of the second type of error handing:
Compilation
in a specific hook.See the Module's error merging as an example https://github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/lib/Compilation.js#L2731-L2740errors array
of parametercompilation
https://github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/lib/DllReferencePlugin.js#L133-L149After the build process is finished,
Errors
andWarnings
are passed toStats
for final processing https://github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/lib/Stats.js#L68-L81The final output will pipe into
stdio
orstderror
.rustc
https://rustc-dev-guide.rust-lang.org/diagnostics.html?highlight=Errors#error-messages, According to rustc-dev-guide,https://rustc-dev-guide.rust-lang.org/diagnostics.html?highlight=Errors#error-messages:~:text=Session%20and%20ParseSess%20have%20methods%20(or%20fields%20with%20methods)%20that%20allow%20reporting%20errors.%20These%20methods%20usually%20have%20names%20like%20span_err%20or%20struct_span_err%20or%20span_warn%2C%20etc...%20There%20are%20lots%20of%20them%3B%20they%20emit%20different%20types%20of%20%22errors%22%2C%20such%20as%20warnings%2C%20errors%2C%20fatal%20errors%2C%20suggestions%2C%20etc. We know that rustc mainly uses Session
structures to report errors, and that Sessions are mounted on the GlobalContext throughout the compilation process.
Let's take the example of rust
TypeError
, https://rustc-dev-guide.rust-lang.org/ty.html#type-errors, When rustc needs to emit a type_error it will callTyCtxt::ty_error
orTyCtxt::ty_error_with_message
. When callingty_error_with_message
it will useSession
to register onedelay_span_bug
and finally call delay_span_bug ofsession.handler
, which will createg aDiagnostic
first, after that callself.emit_diagnostic
, finally callself.emitter.emit_diagnostic
https://github.com/rust-lang/rust/blob/b998821e4c51c44a9ebee395c91323c374236bbb/compiler/rustc_errors/src/emitter.rs#L614-L638, through a number of transformation operations https://github.com/rust-lang/rust/blob/b998821e4c51c44a9ebee395c91323c374236bbb/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs#L21 pipe the result tostderr
Unresolved questions
Which Error Reporter should we use?
Some alternative options:
How to unify error handing in rust side and node side.
serde
serde
Future possibilities
Provide a unique
Error Number
for each type of error as rustc and typescript did.rustc
tsc
Pros:
For the above wrong rust code snippet, we can find specific explanations on the official website of rust https://doc.rust-lang.org/error-index.html#E0282
Cons:
Beta Was this translation helpful? Give feedback.
All reactions