【发布时间】:2017-10-18 13:06:25
【问题描述】:
我试图为我的 Angular4 应用程序实现一个通用的 ErrorHandler,目的是显示一个对话框,其中包含有关我收到的错误的一些信息。
这是错误处理程序:
import { ErrorHandler, Injectable, Injector } from '@angular/core'
// import { Router } from '@angular/router'
import { MatDialog } from '@angular/material'
import { HttpErrorResponse } from '@angular/common/http'
import { MessageDialog } from './message.dialog'
// import { LoginService } from '../login/main.service'
@Injectable()
export class DialogErrorHandler implements ErrorHandler {
constructor(private injector: Injector) {
}
handleError(error: any): void {
let localError = error;
let finalMessage: string = "Errore sconosciuto";
let finalCallback: () => void = () => { console.log("default callback")};
let dialog: MatDialog = this.injector.get(MatDialog);
// let login: LoginService = this.injector.get(LoginService);
// let router: Router = this.injector.get(Router);
if( localError instanceof HttpErrorResponse && localError.error instanceof Error){
localError = localError.error
}
if (localError instanceof HttpErrorResponse) {
console.log("http error");
let errorDesc = localError.status + " " + localError.statusText + ": ";
switch (localError.status) {
case 403:
finalMessage = "La sessione è scaduta, ripeti il login.";
// finalCallback = () => { login.logout(); router.navigate['/login']; };
break;
case 500:
finalMessage = "Errore sul server - " + errorDesc + localError.error;
break;
default:
finalMessage = errorDesc;
}
} else {
finalMessage = localError.toString();
finalCallback = () => { location.reload() };
}
dialog.open(MessageDialog, {
data: {
message: finalMessage,
callback: finalCallback
}
})
console.log(error);
}
}
虽然这是对话框:
import { Component, Inject } from '@angular/core'
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'
@Component({
selector: 'message-dialog',
template: `
<p mat-dialog-title color="primary" class="centered">Attenzione</p>
<div mat-dialog-content>{{message}}</div>
<div mat-dialog-actions style="display: flex; justify-content: center">
<button mat-button mat-dialog-close (click)="handleClick()">
OK
</button>
</div>
`,
styleUrls: ['../common/style.css']
})
export class MessageDialog {
message: string = "cose";
callback: () => void;
constructor( @Inject(MAT_DIALOG_DATA) private data,
private diagref: MatDialogRef<MessageDialog>) {
if (data) {
this.message = data.message;
this.callback = data.callback;
}
}
handleClick() {
this.diagref.close();
if (this.callback) {
this.callback();
}
}
}
这是我遇到的问题:https://plnkr.co/edit/dZ9yNf?p=preview
现在,问题是在我启动错误后,我显示的 MatDialog 不显示消息并且不关闭。它正确地执行了回调函数,但它停留在那里。
- 我无法重现 plunkr 中的行为。我不知道为什么,但我怀疑这与 plunkr 将我的 HttpErrorResponse 对象包装在另一个错误中这一事实有关。尽管如此,在我的开发环境中,即使我注释了所有考虑错误类型的代码,错误仍然存在。
- 我试过用 MatSnackBar 代替 MatDialog,不走运,还是同样的问题,snackbar 出现并且不想消失。
- 对话框本身也用于其他情况,在这些情况下它会正常关闭,不会产生任何问题。
- 调试我发现问题在于对话框以某种方式尝试自行关闭,但从未发出 MatDialogContainer 上的状态更改事件,因为在执行之后我看到状态更改但没有调用回调。
我做错了什么?为什么会有这种奇怪的行为?你有什么建议吗?
附:评论的东西是我需要的东西,但我已经能够在不解决问题的情况下取出来简化处理程序。它在那里,不会被注释,但这不是问题。
编辑:经过 9 天,风滚草徽章和其他东西,我已经能够重现错误。同样的 plunkr,不同之处在于错误的来源。特别是:
handleClick(){
Observable.throw(new Error("local error")).subscribe(
() => {},
(err) => {throw err)
)
}
throwError(){
this.http.get("http://www.google.com/thisshouldnotexist").subscribe(
() => {},
(err) => {throw err}
)
}
在这种情况下,handleClick 顺利进行,而throwError 则挂在那里。如果有人知道解决方案,请帮助。
【问题讨论】:
标签: angular typescript error-handling dialog material-design