我确实使用第三方API来管理身份验证操作。
可用的方法返回promise,假设有一个createUser
方法,我可以这样称呼:
this.auth.createUser(data).then(() => alert('user created'));
到目前为止还可以。
如果我确实发送了无效的数据,或者如果我打破了一些先决条件,则API会因大量数据和信息而引发一些重大错误。问题在于这些错误对用户不友好。
我正在尝试包装这些方法,因此我可以抛出一个已知的错误(特定标记)并向用户提供更好的消息,但到目前为止,我仍然无法做到这一点。
我已经创建了以下代码段:
class Auth {
createUser(...args) {
return new Promise((resolve, reject) => {
setTimeout(() => {
this.log(...args);
throw new Error('auth service throws some error with a lot of details and info not user friendly');
}, 3000);
});
}
log(...args) { console.log('this', ...args) }
}
const auth = new Auth();
Object.keys(auth).forEach(key => {
if (typeof auth[key] === 'function') {
const originalFunction = auth[key];
auth[key] = function() {
try {
return originalFunction.apply(this, arguments);
} catch (e) {
this.log('error', e);
throw new Error('error-auth-' + nameFunctionAsTag(key));
}
};
} else {
console.log(typeof auth[key]);
}
});
function nameFunctionAsTag(name) {
return name.replace(/(?!^)[A-Z]/g, c => '-' + c.toLowerCase());
}
auth.log('auth service');
auth.createUser(1, 2, 3, 4, 5);
// expected: error-auth-create-user
// received: auth service throws some error with a lot of details and info not user friendly
如后两行代码所述,我希望能捕获到该错误并收到error-auth-create-user
,但我不明白为什么它不起作用。
感谢您的帮助,谢谢。
答案 0 :(得分:1)
使用决心,拒绝诺言。
此处(您的代码):
try {
return originalFunction.apply(this, arguments); // asynchronous because of setTimeOut
} catch (e) {
this.log('error', e);
throw new Error('error-auth-' + nameFunctionAsTag(key));
}
// 3 second later, trigger exception out of try/catch statement
您可以做什么:
function asyncError(){
return new Promise(function(resolve, reject){
// ... code
reject(new Error('Error ...'));
// ... code
})
}
async function test(){
try{
const experiment = await asyncError();
}
catch(e){
console.log(e)
}
}
其他方式(无需等待即可捕获):
function test2(){
asyncError().catch((e) => console.log(e));
}
答案 1 :(得分:1)
注册Promise或setTimeout时,不会在同一堆栈上下文中调用该函数。您实际上是在告诉引擎注册回调,然后系统将在以后使用正确的参数调用它。因此,错误永远不会达到尝试/捕获的目的。您可以在异步函数中利用await关键字来暂停执行并在以后返回,并保持相同的上下文,这将保留此处的try / catch块。这是您在这里需要做的。检出:https://levelup.gitconnected.com/the-definite-guide-to-handling-errors-gracefully-in-javascript-58424d9c60e6
答案 2 :(得分:0)
刚刚发现了主要问题:Object.keys(auth)
在类实例上返回了空数组。
将其更改为Object.getOwnPropertyNames(Object.getPrototypeOf(auth))
之后,我可以专注于大家都帮助过我的诺言:)
我最后的工作片段以这种方式结束:
class Auth {
createUser(...args) {
return Promise.resolve().then(() => {
this.log(...args);
throw new Error('auth service throws some error with a lot of details and info not user friendly');
});
}
log(...args) { console.log('this', ...args) }
}
const auth = new Auth();
Object.getOwnPropertyNames(Object.getPrototypeOf(auth)).forEach(key => {
if (key === 'constructor') return;
if (typeof auth[key] === 'function') {
const originalFunction = auth[key];
auth[key] = function() {
return Promise.resolve()
.then(() => originalFunction.apply(this, arguments))
.catch(e => {
this.log('error', e.message);
throw new Error('error-auth-' + nameFunctionAsTag(key));
});
};
}
});
function nameFunctionAsTag(name) {
return name.replace(/(?!^)[A-Z]/g, c => '-' + c.toLowerCase());
}
auth.log('auth service');
auth.createUser(1, 2, 3, 4, 5).catch(e => console.log('final error:', e.message));
谢谢大家的帮助:)