【问题标题】:How can I catch components errors on server in angular universal?如何在 Angular Universal 中捕获服务器上的组件错误?
【发布时间】:2018-12-29 01:29:34
【问题描述】:

这是我的服务器代码,下一个片段渲染角度home.comnponent

app.get("*", (req, res) => {
    res.render(
        `../${CLIENT_DIST_DIR}/index`,
        {
            req: req,
            res: res,
            providers: [
                {
                    provide: REQUEST, useValue: (req)
                },
                {
                    provide: RESPONSE, useValue: (res)
                },
                {
                    provide: "ORIGIN_URL",
                    useValue: (`${http}://${req.headers.host}`)
                }
            ]
        },
        (err, html) => {
            if (err) {
                Log.error("NG render error", err);
                throw err;
            }
            res.send(html);
        }
    );
});

这是我的home.component 错误:

@Component({
    selector: "app-home",
    templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {
    constructor(private http: TransferHttpService,
                @Inject(AppStorage) private appStorage: Storage) {
    }

    ngOnInit(): void {
         let t = null;
         console.log(t["sd"]["sd"]["sd"]);
    }
}

在控制台我得到错误,没关系:

ERROR TypeError: Cannot read property 'sd' of undefined
    at HomeComponent.ngOnInit (nodejs\dist\proxy\server.js:1402:58876)
    at checkAndUpdateDirectiveInline (nodejs\dist\proxy\server.js:47324:19)
    at checkAndUpdateNodeInline (nodejs\dist\proxy\server.js:48588:20)
    at checkAndUpdateNode (nodejs\dist\proxy\server.js:48550:16)

但是在回调中这个条件不起作用:

.....
(err, html) => {
                if (err) {
                    Log.error("NG render error", err);
                    throw err;
                }
                res.send(html);
            }
.....

在这里,err == null。为什么?

我想在服务器上记录此类错误并将它们写入文件。

怎么做?

【问题讨论】:

  • 你检查过服务器运行的终端,我认为它正在终端中打印。可能是快速渲染引擎生成带有错误的html而不给出错误
  • @RaviSevta 是的,它在本地工作。问题是err 始终是null。我这样设置视图引擎:app.set("view engine", "html"); app.set("views", CLIENT_APP_DIR);

标签: javascript node.js angular angular-universal server-side-rendering


【解决方案1】:

我不确定为什么它不起作用,但作为一种解决方法,您可以尝试实现一个自定义错误处理程序,它会捕获这种错误并将其分配给服务器端提供的变量

角度错误处理程序

import {Optional, Injectable, ErrorHandler } from '@angular/core';

@Injectable()
export class CustomErrorHandlerService extends ErrorHandler{

  constructor( @Optional() @Inject('ERROR_WRAPPER') private errorWrapper: any ) { 

  }

  handleError(error: Error) {

    console.log('Custom Error Handler error: ' + error.toString());
    if(this.errorWrapper)//serverSide
    {
        this.errorWrapper.error = error;
    }
  }

}

应用模块

  providers: [
  //...
  {
    provide: ErrorHandler, useClass:
    CustomErrorHandlerService
  }] 

通用服务器

app.get("*", (req, res) => {

    let errorWrapper = {
    error: any;
    }

    res.render(
        `../${CLIENT_DIST_DIR}/index`,
        {
            req: req,
            res: res,
            providers: [
                {
                    provide: REQUEST, useValue: (req)
                },
                {
                    provide: RESPONSE, useValue: (res)
                },
                { 
                    provide: ERROR_WRAPPER, useValue: (errorWrapper)
                },
                {
                    provide: "ORIGIN_URL",
                    useValue: (`${http}://${req.headers.host}`)
                }
            ]
        },
        (err, html) => {
            if (err) {
                Log.error("NG render error", err);
                throw err;
            }
            if(errorWrapper.error)
            {
                //handle your error here
            }
            res.send(html);
        }
    );
});

如果您只想按原样抛出错误,您可以直接使用RESPONSE 令牌并在错误处理程序中设置正确的状态码和正文

【讨论】:

  • ERROR_WRAPPER 来自哪里?
  • 您可以使用您想要的名称(只要提供者和组件使用相同的名称),但最好是创建一个注入令牌
  • 但是当我在serve.ts 调用ERROR_WRAPPER 时,ERROR_WRAPPER 需要一个导入引用
  • 尝试在server.ts中使用引号,例如provide: 'ERROR_WRAPPER',
  • 您似乎没有在回调中与错误包装器交互,错误如何使用您的自定义 errorWrapper 对象进入回调错误对象?因为它是一个自定义对象,所以我看不到您告诉 angular 将错误发送到 res.render 回调的位置
猜你喜欢
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
相关资源
最近更新 更多