0

I am having trouble "catching" an error using either a try/catch or .catch statement, and I believe it is because the error is not being thrown in a "conventional" manner. At the top-level, I have an invocation of a function within an async function:

async function main() {
    let computedValue;
    try {
      computedValue = await module.doComputation();
    } catch (err) {
      console.log("We caught the error!")
      computedValue = null;
    }
}
// in `module`
import $ from 'jquery';

export function doComputation() {
  return new Promise((resolve) => {
    $.ajax({
      type: 'GET',
      url: location.href,
      success: (data) => {
        const text = $($.parseHTML(data)).find('#some-dom-element').text()
        const total = text.match(/[+-]?\d+(\.\d+)?/g)[0]; // this line throws an error!
        if (total > 0) {
          resolve(total);
        }
      },
      error: () => {
        resolve(-1);
      },
    });
  });
}

When I run this, the exception that is thrown from within doComputation is unhandled, and it looks like: Uncaught TypeError: Cannot read properties of null (reading '0')

I am not particularly surprised that this function threw an error (and I understand why), however I need to be sure that main can safely catch the error that this function throws.

Importantly, I would really prefer to be able to catch this error at the level of main (technically there are hundreds of different implementations of doComputation in my project and having to modify all of them would be a tad difficult).

Does anyone have any ideas about how I might solve this problem? Adding a .catch to await module.doComputation does not seem to do the trick and also makes my LSP unhappy.

I tried adding a .catch statement to the offending line, and also wrapping the entire statement in a try/catch, but to no avail.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
maudel
  • 1
  • 1
  • [Don't use `success` and `error` callbacks](https://stackoverflow.com/q/6285407/1048572). Use `$.ajax({type:…, url:…}).then()` - or even just `const data = await $.ajax(…)`. [Don't use `new Promise`](https://stackoverflow.com/a/31327725/1048572). – Bergi Apr 05 '22 at 10:41
  • You could use `reject` instead of `resolve` on the error function. – Phiter Apr 05 '22 at 10:41

1 Answers1

-1

You should include a reject variable in your promise and handle the error that way

return new Promise((resolve,reject) => {
$.ajax({
  type: 'GET',
  url: location.href,
  success: (data) => {
    const text = $($.parseHTML(data)).find('#some-dom-element').text()
    const total = text.match(/[+-]?\d+(\.\d+)?/g)[0]; // this line throws an error!
    if (total > 0) {
      resolve(total);
    }
  },
  error: () => {
    reject(-1)
  },
  });
 });
}

And in main

function main() {
let computedValue;

  module.doComputation().then((res) => {
      computedValue = res
  }).catch(()=>{
     console.log("We caught the error!")
     computedValue = null;
  })
}

Hope this helps!

Orçun Güler
  • 118
  • 1
  • 6
  • Thanks! This will help. Is there any way I can catch the error without modifying `doComputation`? – maudel Apr 05 '22 at 11:01
  • 1
    To throw an error you need to use the reject method provided from Promise object but you probably should listen to @Bergi I'm also fairly new to Javascript. – Orçun Güler Apr 05 '22 at 11:05