summaryrefslogtreecommitdiffstats
path: root/third_party/rust/error-support/src/handling.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/error-support/src/handling.rs
parentInitial commit. (diff)
downloadfirefox-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.rs112
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
+}