parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀
https://parceljs.org
MIT License
43.41k stars 2.26k forks source link

Add diagnostics using anyhow #9824

Closed MonicaOlejniczak closed 3 months ago

MonicaOlejniczak commented 3 months ago

↪️ Pull Request

This pull request primarily introduce a diagnostic! and diagnostic_error! macro to build diagnostics. These macros both attach an origin automatically using the builtin module_path!() macro, which will refer to the caller of the macro. The diagnostic macros are preferred over using factory functions like Diagnostic::new() or Diagnostic::default() so that the origin field actually refers to the caller of the diagnostic, not the diagnostic module itself. If more diagnostic details are required by users, then file tracing or rust backtraces should be enabled.

These changes have updated most usages of anyhow! to diagnostic_error! to demonstrate the usage of the API. It is designed in a way that is similar to anyhow, in that you can provide a string literal or formatted string. One difference is that a DiagnosticBuilder can be provided as an input to partially construct the Diagnostic whilst also adding an origin. Note that Diagnostic::default() is specifically unimplemented to guide developers towards using the new macros.

Other notable changes include:

The next iteration of these changes will be to remove anyhow! in the diagnostic_error! macro and instead return diagnostic errors in all fns.

💻 Examples

Simple message

diagnostic_error!("Failed to find request node");

Formatted message

diagnostic_error!(
  "Failed to resolve {} from {}",
  self.dependency.specifier,
  from.display()
);

Complex diagnostic

diagnostic_error!(DiagnosticBuilder::default()
  .code_frames(vec![CodeFrame::from(package_json)])
  .message(format!(
    "Declared output format {output_format} does not match expected output format {inferred_output_format}"
  )));

🚨 Test instructions

cargo test