2016-08-26 1 views
2

プロキシハンドラ内でReflect.get(target, name, receiver)によって非同期的にスローされるエラーをキャッチするにはどうすればよいですか?非同期プロキシ/リフレクトトラップでエラーをキャッチする方法

私は、任意のネットワークの例外をキャッチし、優雅にユーザーにエラーメッセージを表示することができるように、APIクラスをラップするProxyReflectを使用しています。 ()決して "エラーをキャッチしていない" Reflect.getの内側にエラーがスローされ

 
//User.js 

class User { 

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

 
//App.js 

import Wrapper from './Wrapper'; 

Wrapper.asyncFunction(); //throws uncaught Error 
 
//API.js 

class API { 
    get user() { 
    return new 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); 

は、印刷され、キャッチされないままにされます。

+0

約束以内意味する「非同期的にスローされますか」? 'Reflect.get(...)'の戻り値に 'catch'ハンドラを付けることができます。 – sdgluck

+0

"非同期にスローする"ことはできません。あなたがすることができるのは、「拒否される約束を返す」ことだけです。 – Bergi

答えて

4

新しいPromiseでReflect.get(...)(実際のAPIメソッド)の戻り値に呼び出しをラップし、エラーをキャッチしてログに記録してから再度渡すことができます。同様に、エラーがない場合は、単に外部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); 
     }); 
    }); 
    } 
}; 

あなたの現在のコードは、非同期関数はその場で実行されていないため、エラーをキャッチされていないので、エラーがtryブロックの外にスローされます。

編集:約束のコンストラクタを使用していない別のアプローチ:

let handler = { 
    get: (target, name, receiver) => { 
    return (...args) => { 
     return Reflect 
     .get(target, name, receiver) 
     .apply(target, args) 
     .catch((e) => { console.log('caught error', e) }); 
    }; 
    } 
}; 
+0

あなたの返事をありがとう、私はReflect.get()もプロミスではない関数を返すことができることを述べている必要があります。 .catch()が未定義の場合、エラーがスローされます。 – Mastergalen

+0

どのような状況でプロミスを返さないでしょうか?あなたのQに 'Wrapper.asyncFunction'のコードを追加してください。常にPromiseを返すようにAPIを修正することをお勧めします。そうしないと、エラーを確実にキャッチできません。 – sdgluck

+0

実際、** Wrapper **には約束を返す関数しかなくても、Reflectに.catch()を追加すると、.catchが未定義のエラーがスローされます。 https://jsfiddle.net/geh2k153/3/ – Mastergalen

関連する問題