如何定位 Angular promise 或 observable 中的错误?
How to locate an error in an Angular promise or observable?
浏览器控制台显示以下错误:
zone.js:668 Error: Uncaught (in promise): [object Undefined]
at resolvePromise (zone.js:814)
at resolvePromise (zone.js:771)
at zone.js:873
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
at invokeTask (zone.js:1540)
at globalZoneAwareCallback (zone.js:1577)
我不知道去哪里查看源代码。
更新:在 Firefox 下打开的同一页面显示消息:
Error: Uncaught (in promise): [object Undefined]
Stack trace:
resolvePromise@http://localhost:4200/polyfills.js:3131:31
makeResolver/<@http://localhost:4200/polyfills.js:3041:17
setError@http://localhost:4200/scripts.js:979:21
messageCallback@http://localhost:4200/scripts.js:1092:25
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:2738:17
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:2505:28
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:2813:24
invokeTask@http://localhost:4200/polyfills.js:3857:9
globalZoneAwareCallback@http://localhost:4200/polyfills.js:3883:17
zone.js:668
更新:如果错误与我新添加的拦截器源代码有关,这里是我如何处理可能的异常:
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return this.addAuthHeader(request, next);
}
private addAuthHeader(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('=======>> Intercepting the http request to add the jwt token in the header');
const tokenPromise: Promise<any> = this.keycloakClientService.getToken();
const tokenObservable: Observable<any> = Observable.fromPromise(tokenPromise);
tokenObservable.map(authToken => {
console.log('Token value: ' + authToken);
// Clone the request before it is sent to the server
// as the original request is immutable and cannot be changed
request = request.clone({
setHeaders: {
'Authorization': AUTH_HEADER_PREFIX + authToken
}
});
console.log('=======>> The request has been cloned');
});
console.log('Handle the request in the interceptor chain');
return next.handle(request)
.catch(response => {
if (response instanceof HttpErrorResponse) {
if (response.status === 401) {
// TODO redirect to the login route or show a modal
}
console.log('The error has been handled by the interceptor', response);
}
return Observable.throw(response);
})
.do((response: HttpEvent<any>) => {
if (response instanceof HttpResponse) {
console.log('The response has been handled by the interceptor', response);
}
});
}
zone.js:668 Error: Uncaught (in promise): [object Undefined]
这是一个发生在您的源代码范围之外的错误。这就是为什么没有与您可以直接调试的内容相关的堆栈跟踪。您可能会尝试更改源代码或添加控制台日志消息,但我猜这不会帮助您找到它。
这很可能是配置错误。
当 Angular 无法加载模块时,您可能会收到此错误。检查每个模块并确保所有声明、导入、导出等都是正确的。确保您使用正确的注入令牌和可注入引用。
如果在应用程序启动后发生这种情况。延迟加载模块可能会失败。再次重复上述步骤。
如果这不能帮助找到原因,那么您需要删除尽可能多的内容,然后慢慢将它们添加回来。直到找到罪魁祸首。
创建一个什么都不做的空组件,并将其作为您的入口组件。注释掉所有提供者并注释掉所有声明。继续注释掉主模块使用的东西,直到应用程序成功启动。
慢慢地,重新添加您的提供程序和声明,直到它再次中断。
这应该可以帮助您缩小模块配置问题所在的范围。希望这就是问题的原因。
当然还有很多其他事情可能会触发此错误。
- 尝试将使用第三方 (none-Angular) 库的源代码包装在
zone.runOutsideAngular(()=>{....})
中,这样任何未处理的错误都不会被区域跟踪。
- 在生产模式下构建您的应用程序,但启用源映射以进行调试。
ng build --prod --sourcemaps
- 添加一个
ErrorHandler
服务,看看它是否捕捉到错误。因为这会让你检查抛出的物体。您可以像这样 {provide: ErrorHandler, useClass: MyHandlerService}
添加一个提供程序到您的模块,其中 MyHandlerService
实现 ErrorHandler
.
this.modalService.open(content, {
ariaLabelledBy: "title",
size: "lg",
backdrop: "static"
}).result.then((acao) => {
}, () => { // Add
});
浏览器控制台显示以下错误:
zone.js:668 Error: Uncaught (in promise): [object Undefined]
at resolvePromise (zone.js:814)
at resolvePromise (zone.js:771)
at zone.js:873
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
at invokeTask (zone.js:1540)
at globalZoneAwareCallback (zone.js:1577)
我不知道去哪里查看源代码。
更新:在 Firefox 下打开的同一页面显示消息:
Error: Uncaught (in promise): [object Undefined]
Stack trace:
resolvePromise@http://localhost:4200/polyfills.js:3131:31
makeResolver/<@http://localhost:4200/polyfills.js:3041:17
setError@http://localhost:4200/scripts.js:979:21
messageCallback@http://localhost:4200/scripts.js:1092:25
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:4200/polyfills.js:2738:17
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:4200/polyfills.js:2505:28
./node_modules/zone.js/dist/zone.js/</ZoneTask.invokeTask@http://localhost:4200/polyfills.js:2813:24
invokeTask@http://localhost:4200/polyfills.js:3857:9
globalZoneAwareCallback@http://localhost:4200/polyfills.js:3883:17
zone.js:668
更新:如果错误与我新添加的拦截器源代码有关,这里是我如何处理可能的异常:
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return this.addAuthHeader(request, next);
}
private addAuthHeader(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('=======>> Intercepting the http request to add the jwt token in the header');
const tokenPromise: Promise<any> = this.keycloakClientService.getToken();
const tokenObservable: Observable<any> = Observable.fromPromise(tokenPromise);
tokenObservable.map(authToken => {
console.log('Token value: ' + authToken);
// Clone the request before it is sent to the server
// as the original request is immutable and cannot be changed
request = request.clone({
setHeaders: {
'Authorization': AUTH_HEADER_PREFIX + authToken
}
});
console.log('=======>> The request has been cloned');
});
console.log('Handle the request in the interceptor chain');
return next.handle(request)
.catch(response => {
if (response instanceof HttpErrorResponse) {
if (response.status === 401) {
// TODO redirect to the login route or show a modal
}
console.log('The error has been handled by the interceptor', response);
}
return Observable.throw(response);
})
.do((response: HttpEvent<any>) => {
if (response instanceof HttpResponse) {
console.log('The response has been handled by the interceptor', response);
}
});
}
zone.js:668 Error: Uncaught (in promise): [object Undefined]
这是一个发生在您的源代码范围之外的错误。这就是为什么没有与您可以直接调试的内容相关的堆栈跟踪。您可能会尝试更改源代码或添加控制台日志消息,但我猜这不会帮助您找到它。
这很可能是配置错误。
当 Angular 无法加载模块时,您可能会收到此错误。检查每个模块并确保所有声明、导入、导出等都是正确的。确保您使用正确的注入令牌和可注入引用。
如果在应用程序启动后发生这种情况。延迟加载模块可能会失败。再次重复上述步骤。
如果这不能帮助找到原因,那么您需要删除尽可能多的内容,然后慢慢将它们添加回来。直到找到罪魁祸首。
创建一个什么都不做的空组件,并将其作为您的入口组件。注释掉所有提供者并注释掉所有声明。继续注释掉主模块使用的东西,直到应用程序成功启动。
慢慢地,重新添加您的提供程序和声明,直到它再次中断。
这应该可以帮助您缩小模块配置问题所在的范围。希望这就是问题的原因。
当然还有很多其他事情可能会触发此错误。
- 尝试将使用第三方 (none-Angular) 库的源代码包装在
zone.runOutsideAngular(()=>{....})
中,这样任何未处理的错误都不会被区域跟踪。 - 在生产模式下构建您的应用程序,但启用源映射以进行调试。
ng build --prod --sourcemaps
- 添加一个
ErrorHandler
服务,看看它是否捕捉到错误。因为这会让你检查抛出的物体。您可以像这样{provide: ErrorHandler, useClass: MyHandlerService}
添加一个提供程序到您的模块,其中MyHandlerService
实现ErrorHandler
.
this.modalService.open(content, {
ariaLabelledBy: "title",
size: "lg",
backdrop: "static"
}).result.then((acao) => {
}, () => { // Add
});