const doSomethingAsync = () => { return new Promise(resolve => { console.log("in doSomethingAsync new Promise") setTimeout(() => resolve('I did something'), 1000) // never completes because this promise settles to Rejected throw new Error("failure before timeout") // Reject }) } const doSomething = async () => { console.log("doSomething") try { let r = await doSomethingAsync() console.log("r", r) } catch (e) { // This error is caught because its wrapping an await // for fun we rethrow it console.log("ERROR", e) throw e } } console.log('before') try { doSomething().catch((e) => { // catch does work here because since it was not an await it just returned the promise // and as such we can catch the promise this way console.log("ERROR3", e) }) } catch (e) { // this error is not caught because `doSomething` was not put in await console.log("ERROR2", e) } console.log('after')