【问题标题】:How to locate an error in an Angular promise or observable?如何定位 Angular Promise 或 observable 中的错误?
【发布时间】:2020-12-06 04:13:50
【问题描述】:

浏览器控制台显示如下错误:

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);
        }
      });
  }

【问题讨论】:

  • 我不确定你能否在你的根模块console.log((new Error('throw')).stack); 中尝试一下constructor
  • [通用评论] 当我收到不知道发生了什么的错误消息时,通常我首先尝试的是 ng serve --prod。这通常会给我在某种程度上与运行时错误相关的构建错误。
  • @Vikas 我将构造函数编码为AppModule() { console.log((new Error('throw')).stack); },但它输出的错误完全相同。
  • 请不要关闭这个问题。虽然我同意这似乎是题外话。此特定错误不是可能出现的随机错误。发生这种情况有特定的原因,我们需要将其记录在互联网上,以便人们找到解决方案。当我遇到这个错误时,你基本上没有希望解决它。直到 Angular 和 WebPack 团队修复他们的代码以使这些错误变得更好。我们真的无能为力让这个“主题化”。
  • 哦哦,等等...你提到这发生在你添加了 http 拦截器之后。您是否可能没有将拦截器中的错误案例包装到Observable.throw/throwError 中,而只是将其保留为纯“错误”?您必须返回 Observable 发出的错误,而不是错误本身。参考:angular.io/guide/http#getting-error-details

标签: angular angular-promise


【解决方案1】:
zone.js:668 Error: Uncaught (in promise): [object Undefined]

这是在您的源代码范围之外发生的错误。这就是为什么没有与您可以直接调试的东西相关的堆栈跟踪。您可能会尝试更改源代码或添加控制台日志消息,但我猜它不会帮助您找到它。

很可能是配置错误。

当 Angular 无法加载模块时,您会收到此错误。检查您的每个模块并确保所有声明、导入、导出等......等等......都是正确的。确保使用正确的注入令牌和可注入引用。

如果这发生在应用程序启动后。延迟加载模块可能是失败的。再次重复上述步骤。

如果这不能帮助找到原因,那么您需要尽可能多地删除并慢慢添加它们。直到找到罪魁祸首。

创建一个什么都不做的空组件,并将其作为入口组件。注释掉你所有的提供者并且注释掉你所有的声明。继续注释主模块使用的东西,直到应用程序成功启动。

慢慢地,重新添加您的提供程序和声明,直到它再次中断。

这应该可以帮助您缩小模块配置中的问题所在。希望这就是问题的原因。

当然还有很多其他的事情会触发这个错误。

  • 尝试将使用第三方(非 Angular)库的源代码封装在 zone.runOutsideAngular(()=&gt;{....}) 中,以便区域不会跟踪任何未处理的错误。
  • 在生产模式下构建您的应用程序,但启用源映射以进行调试。 ng build --prod --sourcemaps
  • 添加ErrorHandler 服务并查看它是否捕获错误。因为这将让您检查抛出的对象。您可以像 {provide: ErrorHandler, useClass: MyHandlerService} 这样在模块中添加提供程序,其中 MyHandlerService 实现 ErrorHandler

【讨论】:

  • 我尝试了生产版本并添加了一个错误处理程序,但它没有捕获错误。只有我自己的虚拟测试错误被捕获。
  • 我查明了错误并在stackoverflow.com/questions/50005495/…进行了描述
  • Angular 6 中的 `--sourcemaps` 选项似乎消失了。这是我的里程:ng build --prod --sourcemaps Unknown option: '--sourcemaps'
  • 我刚刚添加了 catch 并解决了感谢 return await this.loadingCtrl.dismiss().then(() => console.log('dismissed')).catch(() => {}) ;
【解决方案2】:
this.modalService.open(content, {
  ariaLabelledBy: "title",
  size: "lg",
  backdrop: "static"
}).result.then((acao) => {

}, () => { // Add

});

【讨论】:

  • 您介意编辑您的答案以包含有关如何解决问题的其他信息吗?
猜你喜欢
  • 2019-03-15
  • 2017-10-15
  • 1970-01-01
  • 2019-01-04
  • 2017-12-22
  • 2019-03-22
  • 2020-04-19
  • 1970-01-01
  • 2021-11-10
相关资源
最近更新 更多