skip to Main Content

I am running automated tests in a Docker container and using a browser in this environment. I have a concern about whether the browser is closing properly in the scenario below. My code includes a try block with an early return statement. My question is: In JavaScript, if I execute an early return in a try block, will the finally block still be triggered? I want to ensure that the browser is closed correctly in my Docker-based test environment.

try {
  await importWallet(params.seedPhrase, page, extensionId)
  await addNetwork({networkName: 'BTC', page, extensionId})
  await connectWallet(context, page)
  return await sendToken({page, params})
}
finally {
  await context.close()
  console.log('🌂 Closing browser')
}

I ran my test, but I am unable to verify it as it runs in a Docker container.

3

Answers


  1. The try statement defines a code block to run (to try).

    The catch statement defines a code block to handle any error.

    The finally statement defines a code block to run regardless of the result.

    The throw statement defines a custom error.

    So for your question, Finally statement will work for sure when you run error handling.

    Login or Signup to reply.
  2. finally block is executed right before returning from try. If you return from finally the returned value from try is ignored despite being evaluated.

    From MDN, when finally is executed (one of the options):

    Immediately before a control-flow statement (return, throw, break,
    continue) is executed in the try block or catch block.

    const logTry = () => new Promise(r => setTimeout(() => r(console.log('try') ?? true), 500));
    
    async function test(){
      try{
        return await logTry();
      }finally{
        console.log('finally');
        return await false;
      }
    }
    
    test().then(console.log);

    The same for throwing an error:

    const logTry = () => new Promise(r => setTimeout(() => r(console.log('try') ?? true), 500));
    
    async function test(){
      try{
        return await logTry(); 
      }finally{
        console.log('finally');
        throw new Error('finally errored');
      }
    }
    
    test().catch(e => console.log(e.message));
    Login or Signup to reply.
  3. I ran my test, but I am unable to verify it as it runs in a Docker container.

    If only there was a convenient JavaScript runtime available in some ubiquitous application like your browser…

    /* Mocks */
    const delayLog = (...args) => new Promise((r) => {
      setTimeout(() => {
        console.log(...args);
        r('token');
      }, 10);
    });
    const importWallet = delayLog.bind(null, 'importWallet');
    const addNetwork = delayLog.bind(null, 'addNetwork');
    const connectWallet = delayLog.bind(null, 'connectWallet');
    const sendToken = delayLog.bind(null, 'sendToken');
    const context = { close: delayLog.bind(null, 'context.close') };
    
    /* Test */
    const asyncTest = async (params, page, extensionId) => {
      try {
        await importWallet(params.seedPhrase, page, extensionId)
        await addNetwork({networkName: 'BTC', page, extensionId})
        await connectWallet(context, page)
        return await sendToken({page, params})
      }
      finally {
        await context.close()
        console.log('🌂 Closing browser')
      }
    }
    
    asyncTest({ seedPhrase: 'acorn' }, 1, '.js').then(console.info);
    .as-console-wrapper { max-height: 100% !important; }

    You can clearly see from the logged output that the async code in the finally is evaluated and awaited before resolving the promise with the return value.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search