1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 use super::action::Action;
5 use bits_client::{
6     bits_protocol::{
7         CancelJobFailure, CompleteJobFailure, HResultMessage, MonitorJobFailure, ResumeJobFailure,
8         SetJobPriorityFailure, SetNoProgressTimeoutFailure, SetUpdateIntervalFailure,
9         StartJobFailure, SuspendJobFailure,
10     },
11     PipeError,
12 };
13 use comedy::error::HResult as ComedyError;
14 use nserror::{nsresult, NS_ERROR_FAILURE};
15 use nsstring::nsCString;
16 use std::convert::From;
17 use xpcom::interfaces::nsIBits;
18 
19 #[derive(Debug, PartialEq, Clone, Copy)]
20 pub enum ErrorType {
21     NullArgument,
22     InvalidArgument,
23     NotInitialized,
24     NoUtf8Conversion,
25     InvalidGuid,
26     PipeNotConnected,
27     PipeTimeout,
28     PipeBadWriteCount,
29     PipeApiError,
30     FailedToCreateBitsJob,
31     FailedToAddFileToJob,
32     FailedToApplyBitsJobSettings,
33     FailedToResumeBitsJob,
34     OtherBitsError,
35     OtherBitsClientError,
36     BitsJobNotFound,
37     FailedToGetBitsJob,
38     FailedToSuspendBitsJob,
39     FailedToCompleteBitsJob,
40     PartiallyCompletedBitsJob,
41     FailedToCancelBitsJob,
42     MissingResultData,
43     MissingCallback,
44     CallbackOnWrongThread,
45     MissingBitsService,
46     BitsServiceOnWrongThread,
47     MissingBitsRequest,
48     BitsRequestOnWrongThread,
49     MissingObserver,
50     ObserverOnWrongThread,
51     MissingContext,
52     ContextOnWrongThread,
53     FailedToStartThread,
54     FailedToConstructTaskRunnable,
55     FailedToDispatchRunnable,
56     TransferAlreadyComplete,
57     OperationAlreadyInProgress,
58     MissingBitsClient,
59     FailedToGetJobStatus,
60     BitsStateError,
61     BitsStateTransientError,
62     BitsStateCancelled,
63     BitsStateUnexpected,
64     FailedToConnectToBcm,
65 }
66 
67 impl ErrorType {
bits_code(&self) -> i3268     pub fn bits_code(&self) -> i32 {
69         let val = match self {
70             ErrorType::NullArgument => nsIBits::ERROR_TYPE_NULL_ARGUMENT,
71             ErrorType::InvalidArgument => nsIBits::ERROR_TYPE_INVALID_ARGUMENT,
72             ErrorType::NotInitialized => nsIBits::ERROR_TYPE_NOT_INITIALIZED,
73             ErrorType::NoUtf8Conversion => nsIBits::ERROR_TYPE_NO_UTF8_CONVERSION,
74             ErrorType::InvalidGuid => nsIBits::ERROR_TYPE_INVALID_GUID,
75             ErrorType::PipeNotConnected => nsIBits::ERROR_TYPE_PIPE_NOT_CONNECTED,
76             ErrorType::PipeTimeout => nsIBits::ERROR_TYPE_PIPE_TIMEOUT,
77             ErrorType::PipeBadWriteCount => nsIBits::ERROR_TYPE_PIPE_BAD_WRITE_COUNT,
78             ErrorType::PipeApiError => nsIBits::ERROR_TYPE_PIPE_API_ERROR,
79             ErrorType::FailedToCreateBitsJob => nsIBits::ERROR_TYPE_FAILED_TO_CREATE_BITS_JOB,
80             ErrorType::FailedToAddFileToJob => nsIBits::ERROR_TYPE_FAILED_TO_ADD_FILE_TO_JOB,
81             ErrorType::FailedToApplyBitsJobSettings => {
82                 nsIBits::ERROR_TYPE_FAILED_TO_APPLY_BITS_JOB_SETTINGS
83             }
84             ErrorType::FailedToResumeBitsJob => nsIBits::ERROR_TYPE_FAILED_TO_RESUME_BITS_JOB,
85             ErrorType::OtherBitsError => nsIBits::ERROR_TYPE_OTHER_BITS_ERROR,
86             ErrorType::OtherBitsClientError => nsIBits::ERROR_TYPE_OTHER_BITS_CLIENT_ERROR,
87             ErrorType::BitsJobNotFound => nsIBits::ERROR_TYPE_BITS_JOB_NOT_FOUND,
88             ErrorType::FailedToGetBitsJob => nsIBits::ERROR_TYPE_FAILED_TO_GET_BITS_JOB,
89             ErrorType::FailedToSuspendBitsJob => nsIBits::ERROR_TYPE_FAILED_TO_SUSPEND_BITS_JOB,
90             ErrorType::FailedToCompleteBitsJob => nsIBits::ERROR_TYPE_FAILED_TO_COMPLETE_BITS_JOB,
91             ErrorType::PartiallyCompletedBitsJob => {
92                 nsIBits::ERROR_TYPE_PARTIALLY_COMPLETED_BITS_JOB
93             }
94             ErrorType::FailedToCancelBitsJob => nsIBits::ERROR_TYPE_FAILED_TO_CANCEL_BITS_JOB,
95             ErrorType::MissingResultData => nsIBits::ERROR_TYPE_MISSING_RESULT_DATA,
96             ErrorType::MissingCallback => nsIBits::ERROR_TYPE_MISSING_CALLBACK,
97             ErrorType::CallbackOnWrongThread => nsIBits::ERROR_TYPE_CALLBACK_ON_WRONG_THREAD,
98             ErrorType::MissingBitsService => nsIBits::ERROR_TYPE_MISSING_BITS_SERVICE,
99             ErrorType::BitsServiceOnWrongThread => nsIBits::ERROR_TYPE_BITS_SERVICE_ON_WRONG_THREAD,
100             ErrorType::MissingBitsRequest => nsIBits::ERROR_TYPE_MISSING_BITS_REQUEST,
101             ErrorType::BitsRequestOnWrongThread => nsIBits::ERROR_TYPE_BITS_REQUEST_ON_WRONG_THREAD,
102             ErrorType::MissingObserver => nsIBits::ERROR_TYPE_MISSING_OBSERVER,
103             ErrorType::ObserverOnWrongThread => nsIBits::ERROR_TYPE_OBSERVER_ON_WRONG_THREAD,
104             ErrorType::MissingContext => nsIBits::ERROR_TYPE_MISSING_CONTEXT,
105             ErrorType::ContextOnWrongThread => nsIBits::ERROR_TYPE_CONTEXT_ON_WRONG_THREAD,
106             ErrorType::FailedToStartThread => nsIBits::ERROR_TYPE_FAILED_TO_START_THREAD,
107             ErrorType::FailedToConstructTaskRunnable => {
108                 nsIBits::ERROR_TYPE_FAILED_TO_CONSTRUCT_TASK_RUNNABLE
109             }
110             ErrorType::FailedToDispatchRunnable => nsIBits::ERROR_TYPE_FAILED_TO_DISPATCH_RUNNABLE,
111             ErrorType::TransferAlreadyComplete => nsIBits::ERROR_TYPE_TRANSFER_ALREADY_COMPLETE,
112             ErrorType::OperationAlreadyInProgress => {
113                 nsIBits::ERROR_TYPE_OPERATION_ALREADY_IN_PROGRESS
114             }
115             ErrorType::MissingBitsClient => nsIBits::ERROR_TYPE_MISSING_BITS_CLIENT,
116             ErrorType::FailedToGetJobStatus => nsIBits::ERROR_TYPE_FAILED_TO_GET_JOB_STATUS,
117             ErrorType::BitsStateError => nsIBits::ERROR_TYPE_BITS_STATE_ERROR,
118             ErrorType::BitsStateTransientError => nsIBits::ERROR_TYPE_BITS_STATE_TRANSIENT_ERROR,
119             ErrorType::BitsStateCancelled => nsIBits::ERROR_TYPE_BITS_STATE_CANCELLED,
120             ErrorType::BitsStateUnexpected => nsIBits::ERROR_TYPE_BITS_STATE_UNEXPECTED,
121             ErrorType::FailedToConnectToBcm => nsIBits::ERROR_TYPE_FAILED_TO_CONNECT_TO_BCM,
122         };
123         val as i32
124     }
125 }
126 
127 impl From<&PipeError> for ErrorType {
from(error: &PipeError) -> Self128     fn from(error: &PipeError) -> Self {
129         match error {
130             PipeError::NotConnected => ErrorType::PipeNotConnected,
131             PipeError::Timeout => ErrorType::PipeTimeout,
132             PipeError::WriteCount(_, _) => ErrorType::PipeBadWriteCount,
133             PipeError::Api(_) => ErrorType::PipeApiError,
134         }
135     }
136 }
137 
138 #[derive(Debug, PartialEq, Clone, Copy)]
139 pub enum ErrorStage {
140     Pretask,
141     CommandThread,
142     AgentCommunication,
143     BitsClient,
144     MainThread,
145 }
146 
147 impl ErrorStage {
bits_code(&self) -> i32148     pub fn bits_code(&self) -> i32 {
149         let val = match self {
150             ErrorStage::Pretask => nsIBits::ERROR_STAGE_PRETASK,
151             ErrorStage::CommandThread => nsIBits::ERROR_STAGE_COMMAND_THREAD,
152             ErrorStage::AgentCommunication => nsIBits::ERROR_STAGE_AGENT_COMMUNICATION,
153             ErrorStage::BitsClient => nsIBits::ERROR_STAGE_BITS_CLIENT,
154             ErrorStage::MainThread => nsIBits::ERROR_STAGE_MAIN_THREAD,
155         };
156         val as i32
157     }
158 }
159 
160 #[derive(Debug, Clone)]
161 pub enum ErrorCode {
162     None,
163     Hresult(i32),
164     Nsresult(nsresult),
165     Message(nsCString),
166 }
167 
168 impl From<ComedyError> for ErrorCode {
from(error: ComedyError) -> Self169     fn from(error: ComedyError) -> Self {
170         ErrorCode::Hresult(error.code())
171     }
172 }
173 
174 impl From<HResultMessage> for ErrorCode {
from(result: HResultMessage) -> Self175     fn from(result: HResultMessage) -> Self {
176         ErrorCode::Hresult(result.hr)
177     }
178 }
179 
180 #[derive(Debug, Clone)]
181 pub struct BitsTaskError {
182     pub error_type: ErrorType,
183     pub error_action: Action,
184     pub error_stage: ErrorStage,
185     pub error_code: ErrorCode,
186 }
187 
188 impl BitsTaskError {
new( error_type: ErrorType, error_action: Action, error_stage: ErrorStage, ) -> BitsTaskError189     pub fn new(
190         error_type: ErrorType,
191         error_action: Action,
192         error_stage: ErrorStage,
193     ) -> BitsTaskError {
194         BitsTaskError {
195             error_type,
196             error_action,
197             error_stage,
198             error_code: ErrorCode::None,
199         }
200     }
201 
missing_result(error_action: Action) -> BitsTaskError202     pub fn missing_result(error_action: Action) -> BitsTaskError {
203         BitsTaskError {
204             error_type: ErrorType::MissingResultData,
205             error_action,
206             error_stage: ErrorStage::MainThread,
207             error_code: ErrorCode::None,
208         }
209     }
210 
from_nsresult( error_type: ErrorType, error_action: Action, error_stage: ErrorStage, error_code: nsresult, ) -> BitsTaskError211     pub fn from_nsresult(
212         error_type: ErrorType,
213         error_action: Action,
214         error_stage: ErrorStage,
215         error_code: nsresult,
216     ) -> BitsTaskError {
217         BitsTaskError {
218             error_type,
219             error_action,
220             error_stage,
221             error_code: ErrorCode::Nsresult(error_code),
222         }
223     }
224 
from_hresult( error_type: ErrorType, error_action: Action, error_stage: ErrorStage, error_code: i32, ) -> BitsTaskError225     pub fn from_hresult(
226         error_type: ErrorType,
227         error_action: Action,
228         error_stage: ErrorStage,
229         error_code: i32,
230     ) -> BitsTaskError {
231         BitsTaskError {
232             error_type,
233             error_action,
234             error_stage,
235             error_code: ErrorCode::Hresult(error_code),
236         }
237     }
238 
from_comedy( error_type: ErrorType, error_action: Action, error_stage: ErrorStage, comedy_error: ComedyError, ) -> BitsTaskError239     pub fn from_comedy(
240         error_type: ErrorType,
241         error_action: Action,
242         error_stage: ErrorStage,
243         comedy_error: ComedyError,
244     ) -> BitsTaskError {
245         BitsTaskError {
246             error_type,
247             error_action,
248             error_stage,
249             error_code: comedy_error.into(),
250         }
251     }
252 
from_pipe(error_action: Action, pipe_error: PipeError) -> BitsTaskError253     pub fn from_pipe(error_action: Action, pipe_error: PipeError) -> BitsTaskError {
254         let error_type = (&pipe_error).into();
255         match pipe_error {
256             PipeError::Api(comedy_error) => BitsTaskError {
257                 error_type,
258                 error_action,
259                 error_stage: ErrorStage::AgentCommunication,
260                 error_code: comedy_error.into(),
261             },
262             _ => BitsTaskError {
263                 error_type,
264                 error_action,
265                 error_stage: ErrorStage::AgentCommunication,
266                 error_code: ErrorCode::None,
267             },
268         }
269     }
270 }
271 
272 impl From<BitsTaskError> for nsresult {
from(error: BitsTaskError) -> Self273     fn from(error: BitsTaskError) -> Self {
274         if let ErrorCode::Nsresult(rv) = error.error_code {
275             rv
276         } else {
277             NS_ERROR_FAILURE
278         }
279     }
280 }
281 
282 impl From<StartJobFailure> for BitsTaskError {
from(error: StartJobFailure) -> Self283     fn from(error: StartJobFailure) -> Self {
284         let error_stage = ErrorStage::BitsClient;
285         let error_action = Action::StartDownload;
286         match error {
287             StartJobFailure::ArgumentValidation(message) => BitsTaskError {
288                 error_type: ErrorType::InvalidArgument,
289                 error_action,
290                 error_stage,
291                 error_code: ErrorCode::Message(nsCString::from(message)),
292             },
293             StartJobFailure::Create(error_code) => BitsTaskError {
294                 error_type: ErrorType::FailedToCreateBitsJob,
295                 error_action,
296                 error_stage,
297                 error_code: error_code.into(),
298             },
299             StartJobFailure::AddFile(error_code) => BitsTaskError {
300                 error_type: ErrorType::FailedToAddFileToJob,
301                 error_action,
302                 error_stage,
303                 error_code: error_code.into(),
304             },
305             StartJobFailure::ApplySettings(error_code) => BitsTaskError {
306                 error_type: ErrorType::FailedToApplyBitsJobSettings,
307                 error_action,
308                 error_stage,
309                 error_code: error_code.into(),
310             },
311             StartJobFailure::Resume(error_code) => BitsTaskError {
312                 error_type: ErrorType::FailedToResumeBitsJob,
313                 error_action,
314                 error_stage,
315                 error_code: error_code.into(),
316             },
317             StartJobFailure::ConnectBcm(error_code) => BitsTaskError {
318                 error_type: ErrorType::FailedToConnectToBcm,
319                 error_action,
320                 error_stage,
321                 error_code: error_code.into(),
322             },
323             StartJobFailure::OtherBITS(error_code) => BitsTaskError {
324                 error_type: ErrorType::OtherBitsError,
325                 error_action,
326                 error_stage,
327                 error_code: error_code.into(),
328             },
329             StartJobFailure::Other(message) => BitsTaskError {
330                 error_type: ErrorType::OtherBitsClientError,
331                 error_action,
332                 error_stage,
333                 error_code: ErrorCode::Message(nsCString::from(message)),
334             },
335         }
336     }
337 }
338 
339 impl From<MonitorJobFailure> for BitsTaskError {
from(error: MonitorJobFailure) -> Self340     fn from(error: MonitorJobFailure) -> Self {
341         let error_stage = ErrorStage::BitsClient;
342         let error_action = Action::MonitorDownload;
343         match error {
344             MonitorJobFailure::ArgumentValidation(message) => BitsTaskError {
345                 error_type: ErrorType::InvalidArgument,
346                 error_action,
347                 error_stage,
348                 error_code: ErrorCode::Message(nsCString::from(message)),
349             },
350             MonitorJobFailure::NotFound => BitsTaskError {
351                 error_type: ErrorType::BitsJobNotFound,
352                 error_action,
353                 error_stage,
354                 error_code: ErrorCode::None,
355             },
356             MonitorJobFailure::GetJob(error_code) => BitsTaskError {
357                 error_type: ErrorType::FailedToGetBitsJob,
358                 error_action,
359                 error_stage,
360                 error_code: error_code.into(),
361             },
362             MonitorJobFailure::ConnectBcm(error_code) => BitsTaskError {
363                 error_type: ErrorType::FailedToConnectToBcm,
364                 error_action,
365                 error_stage,
366                 error_code: error_code.into(),
367             },
368             MonitorJobFailure::OtherBITS(error_code) => BitsTaskError {
369                 error_type: ErrorType::OtherBitsError,
370                 error_action,
371                 error_stage,
372                 error_code: error_code.into(),
373             },
374             MonitorJobFailure::Other(message) => BitsTaskError {
375                 error_type: ErrorType::OtherBitsClientError,
376                 error_action,
377                 error_stage,
378                 error_code: ErrorCode::Message(nsCString::from(message)),
379             },
380         }
381     }
382 }
383 
384 impl From<SuspendJobFailure> for BitsTaskError {
from(error: SuspendJobFailure) -> Self385     fn from(error: SuspendJobFailure) -> Self {
386         let error_stage = ErrorStage::BitsClient;
387         let error_action = Action::Suspend;
388         match error {
389             SuspendJobFailure::NotFound => BitsTaskError {
390                 error_type: ErrorType::BitsJobNotFound,
391                 error_action,
392                 error_stage,
393                 error_code: ErrorCode::None,
394             },
395             SuspendJobFailure::GetJob(error_code) => BitsTaskError {
396                 error_type: ErrorType::FailedToGetBitsJob,
397                 error_action,
398                 error_stage,
399                 error_code: error_code.into(),
400             },
401             SuspendJobFailure::SuspendJob(error_code) => BitsTaskError {
402                 error_type: ErrorType::FailedToSuspendBitsJob,
403                 error_action,
404                 error_stage,
405                 error_code: error_code.into(),
406             },
407             SuspendJobFailure::ConnectBcm(error_code) => BitsTaskError {
408                 error_type: ErrorType::FailedToConnectToBcm,
409                 error_action,
410                 error_stage,
411                 error_code: error_code.into(),
412             },
413             SuspendJobFailure::OtherBITS(error_code) => BitsTaskError {
414                 error_type: ErrorType::OtherBitsError,
415                 error_action,
416                 error_stage,
417                 error_code: error_code.into(),
418             },
419             SuspendJobFailure::Other(message) => BitsTaskError {
420                 error_type: ErrorType::OtherBitsClientError,
421                 error_action,
422                 error_stage,
423                 error_code: ErrorCode::Message(nsCString::from(message)),
424             },
425         }
426     }
427 }
428 
429 impl From<ResumeJobFailure> for BitsTaskError {
from(error: ResumeJobFailure) -> Self430     fn from(error: ResumeJobFailure) -> Self {
431         let error_stage = ErrorStage::BitsClient;
432         let error_action = Action::Resume;
433         match error {
434             ResumeJobFailure::NotFound => BitsTaskError {
435                 error_type: ErrorType::BitsJobNotFound,
436                 error_action,
437                 error_stage,
438                 error_code: ErrorCode::None,
439             },
440             ResumeJobFailure::GetJob(error_code) => BitsTaskError {
441                 error_type: ErrorType::FailedToGetBitsJob,
442                 error_action,
443                 error_stage,
444                 error_code: error_code.into(),
445             },
446             ResumeJobFailure::ResumeJob(error_code) => BitsTaskError {
447                 error_type: ErrorType::FailedToResumeBitsJob,
448                 error_action,
449                 error_stage,
450                 error_code: error_code.into(),
451             },
452             ResumeJobFailure::ConnectBcm(error_code) => BitsTaskError {
453                 error_type: ErrorType::FailedToConnectToBcm,
454                 error_action,
455                 error_stage,
456                 error_code: error_code.into(),
457             },
458             ResumeJobFailure::OtherBITS(error_code) => BitsTaskError {
459                 error_type: ErrorType::OtherBitsError,
460                 error_action,
461                 error_stage,
462                 error_code: error_code.into(),
463             },
464             ResumeJobFailure::Other(message) => BitsTaskError {
465                 error_type: ErrorType::OtherBitsClientError,
466                 error_action,
467                 error_stage,
468                 error_code: ErrorCode::Message(nsCString::from(message)),
469             },
470         }
471     }
472 }
473 
474 impl From<SetJobPriorityFailure> for BitsTaskError {
from(error: SetJobPriorityFailure) -> Self475     fn from(error: SetJobPriorityFailure) -> Self {
476         let error_stage = ErrorStage::BitsClient;
477         let error_action = Action::SetPriority;
478         match error {
479             SetJobPriorityFailure::NotFound => BitsTaskError {
480                 error_type: ErrorType::BitsJobNotFound,
481                 error_action,
482                 error_stage,
483                 error_code: ErrorCode::None,
484             },
485             SetJobPriorityFailure::GetJob(error_code) => BitsTaskError {
486                 error_type: ErrorType::FailedToGetBitsJob,
487                 error_action,
488                 error_stage,
489                 error_code: error_code.into(),
490             },
491             SetJobPriorityFailure::ApplySettings(error_code) => BitsTaskError {
492                 error_type: ErrorType::FailedToApplyBitsJobSettings,
493                 error_action,
494                 error_stage,
495                 error_code: error_code.into(),
496             },
497             SetJobPriorityFailure::ConnectBcm(error_code) => BitsTaskError {
498                 error_type: ErrorType::FailedToConnectToBcm,
499                 error_action,
500                 error_stage,
501                 error_code: error_code.into(),
502             },
503             SetJobPriorityFailure::OtherBITS(error_code) => BitsTaskError {
504                 error_type: ErrorType::OtherBitsError,
505                 error_action,
506                 error_stage,
507                 error_code: error_code.into(),
508             },
509             SetJobPriorityFailure::Other(message) => BitsTaskError {
510                 error_type: ErrorType::OtherBitsClientError,
511                 error_action,
512                 error_stage,
513                 error_code: ErrorCode::Message(nsCString::from(message)),
514             },
515         }
516     }
517 }
518 
519 impl From<SetNoProgressTimeoutFailure> for BitsTaskError {
from(error: SetNoProgressTimeoutFailure) -> Self520     fn from(error: SetNoProgressTimeoutFailure) -> Self {
521         use self::SetNoProgressTimeoutFailure::*;
522 
523         let error_stage = ErrorStage::BitsClient;
524         let error_action = Action::SetNoProgressTimeout;
525         match error {
526             NotFound => BitsTaskError {
527                 error_type: ErrorType::BitsJobNotFound,
528                 error_action,
529                 error_stage,
530                 error_code: ErrorCode::None,
531             },
532             GetJob(error_code) => BitsTaskError {
533                 error_type: ErrorType::FailedToGetBitsJob,
534                 error_action,
535                 error_stage,
536                 error_code: error_code.into(),
537             },
538             ApplySettings(error_code) => BitsTaskError {
539                 error_type: ErrorType::FailedToApplyBitsJobSettings,
540                 error_action,
541                 error_stage,
542                 error_code: error_code.into(),
543             },
544             ConnectBcm(error_code) => BitsTaskError {
545                 error_type: ErrorType::FailedToConnectToBcm,
546                 error_action,
547                 error_stage,
548                 error_code: error_code.into(),
549             },
550             OtherBITS(error_code) => BitsTaskError {
551                 error_type: ErrorType::OtherBitsError,
552                 error_action,
553                 error_stage,
554                 error_code: error_code.into(),
555             },
556             Other(message) => BitsTaskError {
557                 error_type: ErrorType::OtherBitsClientError,
558                 error_action,
559                 error_stage,
560                 error_code: ErrorCode::Message(nsCString::from(message)),
561             },
562         }
563     }
564 }
565 
566 impl From<SetUpdateIntervalFailure> for BitsTaskError {
from(error: SetUpdateIntervalFailure) -> Self567     fn from(error: SetUpdateIntervalFailure) -> Self {
568         let error_stage = ErrorStage::BitsClient;
569         let error_action = Action::SetMonitorInterval;
570         match error {
571             SetUpdateIntervalFailure::ArgumentValidation(message) => BitsTaskError {
572                 error_type: ErrorType::InvalidArgument,
573                 error_action,
574                 error_stage,
575                 error_code: ErrorCode::Message(nsCString::from(message)),
576             },
577             SetUpdateIntervalFailure::NotFound => BitsTaskError {
578                 error_type: ErrorType::BitsJobNotFound,
579                 error_action,
580                 error_stage,
581                 error_code: ErrorCode::None,
582             },
583             SetUpdateIntervalFailure::Other(message) => BitsTaskError {
584                 error_type: ErrorType::OtherBitsClientError,
585                 error_action,
586                 error_stage,
587                 error_code: ErrorCode::Message(nsCString::from(message)),
588             },
589         }
590     }
591 }
592 
593 impl From<CompleteJobFailure> for BitsTaskError {
from(error: CompleteJobFailure) -> Self594     fn from(error: CompleteJobFailure) -> Self {
595         let error_stage = ErrorStage::BitsClient;
596         let error_action = Action::Complete;
597         match error {
598             CompleteJobFailure::NotFound => BitsTaskError {
599                 error_type: ErrorType::BitsJobNotFound,
600                 error_action,
601                 error_stage,
602                 error_code: ErrorCode::None,
603             },
604             CompleteJobFailure::GetJob(error_code) => BitsTaskError {
605                 error_type: ErrorType::FailedToGetBitsJob,
606                 error_action,
607                 error_stage,
608                 error_code: error_code.into(),
609             },
610             CompleteJobFailure::CompleteJob(error_code) => BitsTaskError {
611                 error_type: ErrorType::FailedToCompleteBitsJob,
612                 error_action,
613                 error_stage,
614                 error_code: error_code.into(),
615             },
616             CompleteJobFailure::PartialComplete => BitsTaskError {
617                 error_type: ErrorType::PartiallyCompletedBitsJob,
618                 error_action,
619                 error_stage,
620                 error_code: ErrorCode::None,
621             },
622             CompleteJobFailure::ConnectBcm(error_code) => BitsTaskError {
623                 error_type: ErrorType::FailedToConnectToBcm,
624                 error_action,
625                 error_stage,
626                 error_code: error_code.into(),
627             },
628             CompleteJobFailure::OtherBITS(error_code) => BitsTaskError {
629                 error_type: ErrorType::OtherBitsError,
630                 error_action,
631                 error_stage,
632                 error_code: error_code.into(),
633             },
634             CompleteJobFailure::Other(message) => BitsTaskError {
635                 error_type: ErrorType::OtherBitsClientError,
636                 error_action,
637                 error_stage,
638                 error_code: ErrorCode::Message(nsCString::from(message)),
639             },
640         }
641     }
642 }
643 
644 impl From<CancelJobFailure> for BitsTaskError {
from(error: CancelJobFailure) -> Self645     fn from(error: CancelJobFailure) -> Self {
646         let error_stage = ErrorStage::BitsClient;
647         let error_action = Action::Cancel;
648         match error {
649             CancelJobFailure::NotFound => BitsTaskError {
650                 error_type: ErrorType::BitsJobNotFound,
651                 error_action,
652                 error_stage,
653                 error_code: ErrorCode::None,
654             },
655             CancelJobFailure::GetJob(error_code) => BitsTaskError {
656                 error_type: ErrorType::FailedToGetBitsJob,
657                 error_action,
658                 error_stage,
659                 error_code: error_code.into(),
660             },
661             CancelJobFailure::CancelJob(error_code) => BitsTaskError {
662                 error_type: ErrorType::FailedToCancelBitsJob,
663                 error_action,
664                 error_stage,
665                 error_code: error_code.into(),
666             },
667             CancelJobFailure::ConnectBcm(error_code) => BitsTaskError {
668                 error_type: ErrorType::FailedToConnectToBcm,
669                 error_action,
670                 error_stage,
671                 error_code: error_code.into(),
672             },
673             CancelJobFailure::OtherBITS(error_code) => BitsTaskError {
674                 error_type: ErrorType::OtherBitsError,
675                 error_action,
676                 error_stage,
677                 error_code: error_code.into(),
678             },
679             CancelJobFailure::Other(message) => BitsTaskError {
680                 error_type: ErrorType::OtherBitsClientError,
681                 error_action,
682                 error_stage,
683                 error_code: ErrorCode::Message(nsCString::from(message)),
684             },
685         }
686     }
687 }
688