diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/error-support/src/handling.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/error-support/src/handling.rs')
-rw-r--r-- | third_party/rust/error-support/src/handling.rs | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/third_party/rust/error-support/src/handling.rs b/third_party/rust/error-support/src/handling.rs new file mode 100644 index 0000000000..f01fbc2b00 --- /dev/null +++ b/third_party/rust/error-support/src/handling.rs @@ -0,0 +1,112 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Helpers for components to "handle" errors. + +/// Describes what error reporting action should be taken. +#[derive(Debug, Default)] +pub struct ErrorReporting { + /// If Some(level), will write a log message at that level. + log_level: Option<log::Level>, + /// If Some(report_class) will call the error reporter with details. + report_class: Option<String>, +} + +/// Specifies how an "internal" error is converted to an "external" public error and +/// any logging or reporting that should happen. +pub struct ErrorHandling<E> { + /// The external error that should be returned. + pub err: E, + /// How the error should be reported. + pub reporting: ErrorReporting, +} + +impl<E> ErrorHandling<E> { + /// Create an ErrorHandling instance with an error conversion. + /// + /// ErrorHandling instance are created using a builder-style API. This is always the first + /// function in the chain, optionally followed by `log()`, `report()`, etc. + pub fn convert(err: E) -> Self { + Self { + err, + reporting: ErrorReporting::default(), + } + } + + /// Add logging to an ErrorHandling instance + pub fn log(self, level: log::Level) -> Self { + Self { + err: self.err, + reporting: ErrorReporting { + log_level: Some(level), + ..self.reporting + }, + } + } + + /// Add reporting to an ErrorHandling instance + pub fn report(self, report_class: impl Into<String>) -> Self { + Self { + err: self.err, + reporting: ErrorReporting { + report_class: Some(report_class.into()), + ..self.reporting + }, + } + } + + // Convenience functions for the most common error reports + + /// log a warning + pub fn log_warning(self) -> Self { + self.log(log::Level::Warn) + } + + /// log an info + pub fn log_info(self) -> Self { + self.log(log::Level::Info) + } + + /// Add reporting to an ErrorHandling instance and also log an Error + pub fn report_error(self, report_class: impl Into<String>) -> Self { + Self { + err: self.err, + reporting: ErrorReporting { + log_level: Some(log::Level::Error), + report_class: Some(report_class.into()), + }, + } + } +} + +/// A trait to define how errors are converted and reported. +pub trait GetErrorHandling { + type ExternalError; + + /// Return how to handle our internal errors + fn get_error_handling(&self) -> ErrorHandling<Self::ExternalError>; +} + +/// Handle the specified "internal" error, taking any logging or error +/// reporting actions and converting the error to the public error. +/// Called by our `handle_error` macro so needs to be public. +pub fn convert_log_report_error<IE, EE>(e: IE) -> EE +where + IE: GetErrorHandling<ExternalError = EE> + std::error::Error, + EE: std::error::Error, +{ + let handling = e.get_error_handling(); + let reporting = handling.reporting; + if let Some(level) = reporting.log_level { + log::log!(level, "{}", e.to_string()); + } + if let Some(report_class) = reporting.report_class { + // notify the error reporter if the feature is enabled. + // XXX - should we arrange for the `report_class` to have the + // original crate calling this as a prefix, or will we still be + // able to identify that? + crate::report_error_to_app(report_class, e.to_string()); + } + handling.err +} |