Mastergalen Mastergalen - 3 months ago 14
Javascript Question

How to catch error in asynchronous Proxy/Reflect trap

How do I catch an error that gets thrown asynchronously by

Reflect.get(target, name, receiver)
within the Proxy handler?

I'm using Proxy and Reflect to wrap an API class, so that I can catch any Network exceptions and gracefully display error messages to the user.


//Wrapper.js

let handler = {
get: (target, name, receiver) => {
try {
Reflect.get(target, name, receiver); //throws Error asynchronously
} catch (e) {
console.log('caught error', e);
}
};

export default new Proxy(new API(), handler);



//App.js

import Wrapper from './Wrapper';

Wrapper.asyncFunction(); //throws uncaught Error



//API.js

class API {
get user() {
return new User()
}
}



//User.js

class User {

/**
* List all users
*/
all() {
return new Promise((resolve, reject) => {
reject(new Error('Network error'));
});
}
}


When an error is thrown, inside Reflect.get() "caught error" never gets printed and remains uncaught.

Answer

By "thrown asynchronously" you mean within a Promise? If so, you could wrap the call to the return value of Reflect.get(...) (the actual API method) in a new Promise, catch any errors, log them, and then pass them on again. Similarly if there are no errors simply resolve the outer Promise.

let handler = {
  get: (target, name, receiver) => {
    return (...args) => new Promise((resolve, reject) => {
      const apiMethod = Reflect.get(target, name, receiver);
      const boundApiMethod = apiMethod.bind(target);

      boundApiMethod(...args).then(resolve, (e) => {
        console.log('caught error', e);
        reject(e);
      });
    });
  }
};

Your current code is not catching the error because asynchronous functions are not executed in-place, so the error is thrown outside of the try block.