如何在 Angular Universal 中捕获服务器上的组件错误?
Posted
技术标签:
【中文标题】如何在 Angular Universal 中捕获服务器上的组件错误?【英文标题】:How can I catch components errors on server in 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);
【参考方案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 回调的位置以上是关于如何在 Angular Universal 中捕获服务器上的组件错误?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Angular Universal 中检测屏幕分辨率?
如何在 Angular 5 (s-s-r with Universal) 中使用 Google Analytics 功能?
如何在 Angular Universal 中获取完整的基本 URL(包括服务器、端口和协议)?
如何正确启动 Angular Universal 到实时服务器
如何让 Angular Universal 为 Firebase Cloud Functions 编译 Typescript