Search code examples
cypressuncaught-exception

Cypress on uncaught exception is not working


I have the following sample script to experiment exception handling in Cypress. But the exception is not being caught. What am I missing here?

Cypress.on('uncaught:exception', (err, runnable) => {
    Cypress.log("this is top-level exception hadling")
    return false
})

context('Actions', () => {
    
    it('sample_testing', () => {
    
        cy.on('uncaught:exception', (err, runnable) => {
            cy.log("this is test-level exception hadling")
            return false
        })
        
        cy.get("#notfound", {timeout:1000})
    })
    
})

Please note that there is no element with id notfound in my web page.


Solution

  • Uncaught exceptions are only for application errors. Failures within the test code are caught by Cypress but are then reported as a test fail.

    Test Fails

    To prevent that, you can use the fail event

    Cypress.on('fail', (error, runnable) => {
      debugger
    
      // we now have access to the err instance
      // and the mocha runnable this failed on
    
      throw error // throw error to have test still fail
    })
    
    it('calls the "fail" callback when this test fails', () => {
      // when this cy.get() fails the callback
      // is invoked with the error
      cy.get('element-that-does-not-exist')
    })
    

    Uncaught exceptions

    Take a look at the recipe Handling Application Errors

    app.js - throws an error

    document.getElementById('error').addEventListener('click', () => {
      console.log('application will throw an error in 1 second')
      setTimeout(() => {
        console.log('application is about to throw an error')
        throw new Error('Things went bad')
      }, 1000)
    })
    

    test - catch the error and selectively ignore if it has a certain message

      it('can be ignored', () => {
        /**
         * By using "cy.on()" we can ignore an exception in the current test only.
         * If you want to register exception handler for all tests using "Cypress.on()"
         * @see https://on.cypress.io/catalog-of-events
         * @param {Error} e The exception we caught
         * @param {Mocha.Runnable} runnable is the current test or hook during which the error is caught
         */
        cy.on('uncaught:exception', (e, runnable) => {
          console.log('error', e)
          console.log('runnable', runnable)
    
          // we can simply return false to avoid failing the test on uncaught error
          // return false
          // but a better strategy is to make sure the error is expected
          if (e.message.includes('Things went bad')) {
            // we expected this error, so let's ignore it
            // and let the test continue
            return false
          }
          // on any other error message the test fails
        })
    
        cy.visit('index.html')
        cy.get('button#error').click()
        // the error happens after 1000ms
        // we can use hard-coded wait, see the other test
        // to learn how to avoid an unnecessary wait
        cy.wait(1500)
      })