This is a design question that came up to me while unit testing. Let's dive into the example:
Imagine this:
async function foo() {
    try {
        return apiCall()
    }
    catch (e) {
        throw new CustomError(e);
    } 
}
async function bar() {
    return foo()
}
async function main() {
    try {
        await bar()
    }catch(e) {
        console.error(e)
    }
}
main()
What do we see here? That the only function that hasn't got a try-catch block is bar. But if foo fails, it should get catched by the main catch.
While unittesting this like
describe('testing bar', () => {
    it('foo should throw', () => {
        foo.mockImplementantion(() => { throw new CustomError('error')});
        bar()
        .then((result) => console.log(result))
        .catch((err) => { exepect(err).toBeInstanceOf(CustomError)}) // this is what we are testing
    })
})
The output we see is that an Unhandled promise rejection is logged in the console.
So, my question is... even if I know that the main() will catch the error, should I use try-catch block inside all async functions?
 
     
     
    