Bug 1893667 - Update startup sequence to allow starting into new profile selector...
[gecko.git] / devtools / shared / async-utils.js
blob98e36eacb1a7899a14803b471e165841f1a8326a
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/. */
5 "use strict";
7 /**
8  * Helpers for async functions. An async function returns a Promise for the
9  * resolution of the function. When the function returns, the promise is
10  * resolved with the returned value. If it throws the promise rejects with
11  * the thrown error.
12  */
14 /**
15  * Adds an event listener to the given element, and then removes its event
16  * listener once the event is called, returning the event object as a promise.
17  * @param  Element element
18  *         The DOM element to listen on
19  * @param  String event
20  *         The name of the event type to listen for
21  * @param  Boolean useCapture
22  *         Should we initiate the capture phase?
23  * @return Promise
24  *         The promise resolved with the event object when the event first
25  *         happens
26  */
27 exports.listenOnce = function listenOnce(element, event, useCapture) {
28   return new Promise(function (resolve) {
29     const onEvent = function (ev) {
30       element.removeEventListener(event, onEvent, useCapture);
31       resolve(ev);
32     };
33     element.addEventListener(event, onEvent, useCapture);
34   });
37 // Return value when `safeAsyncMethod` catches an error.
38 const SWALLOWED_RET = Symbol("swallowed");
40 /**
41  * Wraps the provided async method in a try/catch block.
42  * If an error is caught while running the method, check the provided condition
43  * to decide whether the error should bubble or not.
44  *
45  * @param  {Function} asyncFn
46  *         The async method to wrap.
47  * @param  {Function} shouldSwallow
48  *         Function that will run when an error is caught. If it returns true,
49  *         the error will be swallowed. Otherwise, it will bubble up.
50  * @param {Mixed} retValue
51  *         Optional value to return when an error is caught and is swallowed.
52  * @return {Function} The wrapped method.
53  */
54 exports.safeAsyncMethod = function (
55   asyncFn,
56   shouldSwallow,
57   retValue = SWALLOWED_RET
58 ) {
59   return async function (...args) {
60     try {
61       const ret = await asyncFn(...args);
62       return ret;
63     } catch (e) {
64       if (shouldSwallow()) {
65         console.warn("Async method failed in safeAsyncMethod", e);
66         return retValue;
67       }
68       throw e;
69     }
70   };