summaryrefslogtreecommitdiffstats
path: root/toolkit/components/bitsdownload/src/bits_interface/dispatch_callback.rs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/bitsdownload/src/bits_interface/dispatch_callback.rs')
-rw-r--r--toolkit/components/bitsdownload/src/bits_interface/dispatch_callback.rs199
1 files changed, 199 insertions, 0 deletions
diff --git a/toolkit/components/bitsdownload/src/bits_interface/dispatch_callback.rs b/toolkit/components/bitsdownload/src/bits_interface/dispatch_callback.rs
new file mode 100644
index 0000000000..b42637a993
--- /dev/null
+++ b/toolkit/components/bitsdownload/src/bits_interface/dispatch_callback.rs
@@ -0,0 +1,199 @@
+/* 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/. */
+use super::{
+ error::{BitsTaskError, ErrorCode, ErrorType},
+ BitsRequest,
+};
+use log::{error, info, warn};
+use nserror::{nsresult, NS_ERROR_FAILURE, NS_OK};
+use xpcom::{
+ interfaces::{nsIBitsCallback, nsIBitsNewRequestCallback},
+ RefPtr,
+};
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub enum IsCallbackExpected {
+ CallbackExpected,
+ CallbackOptional,
+}
+pub use self::IsCallbackExpected::{CallbackExpected, CallbackOptional};
+
+// This is meant to be called at the end of a nsIBits Task. It attempts to
+// return the result via the callback given. If the callback is unavailable, a
+// log message will be printed indicating the results and (possibly) warning
+// than an expected callback was missing.
+pub fn maybe_dispatch_request_via_callback(
+ result: Result<RefPtr<BitsRequest>, BitsTaskError>,
+ maybe_callback: Result<&nsIBitsNewRequestCallback, BitsTaskError>,
+ expected: IsCallbackExpected,
+) -> Result<(), nsresult> {
+ if let Err(error) = maybe_callback.as_ref() {
+ if expected == CallbackExpected || error.error_type == ErrorType::CallbackOnWrongThread {
+ error!(
+ "Unexpected error when {} - No callback: {:?}",
+ error.error_action.description(),
+ error,
+ );
+ }
+ }
+ match result {
+ Ok(request) => match (maybe_callback, expected) {
+ (Ok(callback), _) => unsafe { callback.Success(request.coerce()) },
+ (Err(error), CallbackExpected) => {
+ error!(
+ "Success {} but there is no callback to return the result with",
+ error.error_action.description(),
+ );
+ NS_ERROR_FAILURE
+ }
+ (Err(error), CallbackOptional) => {
+ info!("Success {}", error.error_action.description());
+ NS_OK
+ }
+ },
+ Err(error) => match (maybe_callback, expected) {
+ (Ok(callback), _) => match error.error_code {
+ ErrorCode::None => unsafe {
+ callback.Failure(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ )
+ },
+ ErrorCode::Hresult(error_code) => unsafe {
+ callback.FailureHresult(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ error_code,
+ )
+ },
+ ErrorCode::Nsresult(error_code) => unsafe {
+ callback.FailureNsresult(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ error_code,
+ )
+ },
+ ErrorCode::Message(message) => unsafe {
+ callback.FailureString(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ &*message,
+ )
+ },
+ },
+ (Err(_), CallbackExpected) => {
+ error!("Error {}: {:?}", error.error_action.description(), error);
+ NS_ERROR_FAILURE
+ }
+ (Err(_), CallbackOptional) => {
+ warn!("Error {}: {:?}", error.error_action.description(), error);
+ NS_ERROR_FAILURE
+ }
+ },
+ }
+ .to_result()
+}
+
+// Intended to be used by an nsIBits XPCOM wrapper to return errors that occur
+// before dispatching a task off-thread. No return value is returned because it
+// will represent the return value of the callback function, which should not be
+// propagated.
+pub fn dispatch_pretask_interface_error(
+ error: BitsTaskError,
+ callback: &nsIBitsNewRequestCallback,
+) {
+ let _ = maybe_dispatch_request_via_callback(Err(error), Ok(callback), CallbackExpected);
+}
+
+// This is meant to be called at the end of a nsIBitsRequest Task. It attempts
+// to return the result via the callback given. If the callback is unavailable,
+// a log message will be printed indicating the results and (possibly) warning
+// than an expected callback was missing.
+pub fn maybe_dispatch_via_callback(
+ result: Result<(), BitsTaskError>,
+ maybe_callback: Result<&nsIBitsCallback, BitsTaskError>,
+ expected: IsCallbackExpected,
+) -> Result<(), nsresult> {
+ if let Err(error) = maybe_callback.as_ref() {
+ if expected == CallbackExpected || error.error_type == ErrorType::CallbackOnWrongThread {
+ error!(
+ "Unexpected error when {} - No callback: {:?}",
+ error.error_action.description(),
+ error,
+ );
+ }
+ }
+ match result {
+ Ok(()) => match (maybe_callback, expected) {
+ (Ok(callback), _) => unsafe { callback.Success() },
+ (Err(error), CallbackExpected) => {
+ error!(
+ "Success {} but there is no callback to return the result with",
+ error.error_action.description(),
+ );
+ NS_ERROR_FAILURE
+ }
+ (Err(error), CallbackOptional) => {
+ info!("Success {}", error.error_action.description());
+ NS_OK
+ }
+ },
+ Err(error) => match (maybe_callback, expected) {
+ (Ok(callback), _) => match error.error_code {
+ ErrorCode::None => unsafe {
+ callback.Failure(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ )
+ },
+ ErrorCode::Hresult(error_code) => unsafe {
+ callback.FailureHresult(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ error_code,
+ )
+ },
+ ErrorCode::Nsresult(error_code) => unsafe {
+ callback.FailureNsresult(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ error_code,
+ )
+ },
+ ErrorCode::Message(message) => unsafe {
+ callback.FailureString(
+ error.error_type.bits_code(),
+ error.error_action.as_error_code(),
+ error.error_stage.bits_code(),
+ &*message,
+ )
+ },
+ },
+ (Err(_), CallbackExpected) => {
+ error!("Error {}: {:?}", error.error_action.description(), error);
+ NS_ERROR_FAILURE
+ }
+ (Err(_), CallbackOptional) => {
+ warn!("Error {}: {:?}", error.error_action.description(), error);
+ NS_ERROR_FAILURE
+ }
+ },
+ }
+ .to_result()
+}
+
+// Intended to be used by an nsIBitsRequest XPCOM wrapper to return errors that
+// occur before dispatching a task off-thread. No return value is returned
+// because it will represent the return value of the callback function, which
+// should not be propagated.
+pub fn dispatch_pretask_request_error(error: BitsTaskError, callback: &nsIBitsCallback) {
+ let _ = maybe_dispatch_via_callback(Err(error), Ok(callback), CallbackExpected);
+}