내 애플 리케이션에서 처리되지 않은 거부를 받고 있지만, 모든 코드가 오류 처리로 올바르게 래핑되었음을 확신했다. 주위를 파고 나면 async/await가 예상대로 작동하지 않는다는 것을 알게되었습니다. 기본적으로 내 비동기 함수는 동기화 오류를 throw하고 그 오류는 잡히지 않은 예외로 처리됩니다. 이것은 try catch에 내 코드를 명시 적으로 래핑 할 때도 발생하지만 오류를 throw하는 sync 메소드를 기다리는 경우에는 발생하지 않습니다.비동기로 동기 오류를 처리하는 방법은 무엇입니까?
그래서 여기 내 테스트 코드입니다 :
function test() {
async function one() {
try {
await three();
} catch (error) {
console.log('caught', new Error().stack);
return error;
}
}
async function three() {
try {
throw new Error();
} catch (e) {
console.log('caught', new Error().stack);
return Promise.reject(e);
}
}
one().then(function (result) {
console.log({result});
}).catch(error => console.log({ error }));
}
process.on('unhandledRejection', (e) => console.log('not caught', e.stack));
test();
여기 내가 콘솔에서 볼 수있는 출력 :
not caught Error
at three$ (imports/access-control/execute-handler.js:25:13)
at tryCatch (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:65:40)
at GeneratorFunctionPrototype.invoke [as _invoke] (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:299:22)
at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:117:21)
at tryCatch (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:65:40)
at invoke (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:155:20)
at /Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:198:11
at callInvokeWithMethodAndArg (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:197:16)
at AsyncIterator.enqueue (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:220:13)
at AsyncIterator.prototype.(anonymous function) [as next] (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:117:21)
caught Error
at one$ (imports/access-control/execute-handler.js:11:29)
at tryCatch (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:65:40)
at GeneratorFunctionPrototype.invoke [as _invoke] (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:299:22)
at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:117:21)
at tryCatch (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:65:40)
at invoke (/Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:155:20)
at /Users/joshuaohlman/Development/Xolvio/xspecs/modules/web-app/node_modules/regenerator-runtime/runtime.js:167:13
at /Users/joshuaohlman/.meteor/packages/promise/.0.8.9.ghfed++os+web.browser+web.cordova/npm/node_modules/meteor-promise/fiber_pool.js:32:39
{ result: [Error] }
(STDERR) [Error] [Function]
그래서 내 질문이 예상되는 동작은 무엇입니까?
그렇다면 비동기 함수를 멋지게 래핑하여 동기식 및 비동기식 오류를 모두 잡아 내 자신을 처리하거나 거절 할 수 있도록 할 수 있습니다.
내 코드를 컴파일하는 데 바벨을 사용하고 있습니다.이 코드는 브라우저에서 코드를 실행하지만 노드에서 실행됩니다. 이 흥미로운 경우
, 여기에 내 코드의 컴파일 된 버전입니다 :
//
function test() { // 6
function one() { // 7
return _regenerator2.default.async(function() { // 7
function one$(_context) { // 7
while (1) { // 7
switch (_context.prev = _context.next) { // 7
case 0: // 7
_context.prev = 0; // 7
_context.next = 3; // 7
return _regenerator2.default.awrap(three()); // 7
//
case 3: // 7
_context.next = 9; // 7
break; // 7
//
case 5: // 7
_context.prev = 5; // 7
_context.t0 = _context["catch"](0); // 7
console.log('caught', new Error().stack); // 11
return _context.abrupt("return", _context.t0); // 7
//
case 9: // 7
case "end": // 7
return _context.stop(); // 7
} // 7
} // 7
} // 7
//
return one$; // 7
}(), null, this, [[0, 5]]); // 7
} // 7
//
function two() { // 15
return _regenerator2.default.async(function() { // 15
function two$(_context2) { // 15
while (1) { // 15
switch (_context2.prev = _context2.next) { // 15
case 0: // 15
_context2.prev = 0; // 15
_context2.next = 3; // 15
return _regenerator2.default.awrap(three()); // 15
//
case 3: // 15
_context2.next = 9; // 15
break; // 15
//
case 5: // 15
_context2.prev = 5; // 15
_context2.t0 = _context2["catch"](0); // 15
console.log('caught', new Error().stack); // 19
return _context2.abrupt("return", _context2.t0); // 15
//
case 9: // 15
case "end": // 15
return _context2.stop(); // 15
} // 15
} // 15
} // 15
//
return two$; // 15
}(), null, this, [[0, 5]]); // 15
} // 15
//
function three() { // 23
return _regenerator2.default.async(function() { // 23
function three$(_context3) { // 23
while (1) { // 23
switch (_context3.prev = _context3.next) { // 23
case 0: // 23
_context3.prev = 0; // 23
throw new Error(); // 23
//
case 4: // 23
_context3.prev = 4; // 23
_context3.t0 = _context3["catch"](0); // 23
console.log('caught', new Error().stack); // 27
return _context3.abrupt("return", Promise.reject(_context3.t0)); // 23
//
case 8: // 23
case "end": // 23
return _context3.stop(); // 23
} // 23
} // 23
} // 23
//
return three$; // 23
}(), null, this, [[0, 4]]); // 23
} // 23
//
one().then(function (result) { // 32
console.log({ // 33
result: result // 33
}); // 33
}).catch(function (error) { // 34
return console.log({ // 34
error: error // 34
}); // 34
}); // 34
} // 35
//
process.on('unhandledRejection', function (e) { // 37
return console.log('not caught', e.stack); // 37
}); // 37
test();
업데이트 내가 재생기 그래서이 가정의 최신 버전을 사용하여이 문제를 재현 할 수없는
버그에서이
내 재생기 또는 바벨 버전 또는 내 환경과 관련된 버전.업데이트
랜스 Whatley는 내가 그 그러나 나는 확실히 기대하고 있지 않다 행동이 그 것이다, 그렇다면 확실하지 않다, 비동기 함수에서 약속을 반환하는 잘못된 있다고 지적 three()
catch 절 내부의 콘솔 로그 문은 호출되지 않습니다.
흥미롭게도, 나는이 코드를 try catch (예 : 오류를 던지는 것)없이 원래 테스트했지만 현재 문제에 대해 당신이 맞다고 생각합니다. 그러나이 경우에도 catch 절은 호출되지 않으며 출력에 두 번째 'catch'콘솔 로그가 포함되지 않는다는 점에 유의해야합니다. – cwohlman
두 번째 생각에 약속을 풀지 않고 약속을 그냥 풀지 않았습니까? 그래서 약속을 되 돌리는 것은 어떤 변화도 가져서는 안된다. 맞습니까? – cwohlman