我試圖爲我的Angular4應用程序實現一般的ErrorHandler,目的是顯示一個對話框,其中包含有關我收到的錯誤的一些信息。使用Material Design的Angular2應用程序的一般錯誤處理程序
這是錯誤處理程序:
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();
}
}
}
這是我得出了一個plunkr:現在https://plnkr.co/edit/dZ9yNf?p=preview
,問題是在我發佈錯誤之後,MatDialog I顯示器不顯示消息並且不關閉。它正確地執行回調函數,但它保持在那裏。
- 我一直無法重現plunkr中的行爲。我不知道爲什麼,但我懷疑它與這個事實有關,plunkr將我的HttpErrorResponse對象包含在另一個錯誤中。儘管如此,在我的開發環境中,即使我評論考慮錯誤類型的所有代碼,也存在錯誤。
- 我試着用MatSnackBar代替MatDialog,沒有運氣,仍然是同樣的問題,小吃店出現並且不想消失。
- 對話框本身也用於其他情況,在正常關閉的情況下,不會給出任何問題。
- 調試我發現問題是,對話框試圖關閉自己,但從未發佈MatDialogContainer上的狀態更改事件,因爲執行後我看到狀態正在改變,但未調用回調。
我在做什麼錯?爲什麼這個奇怪的行爲你有什麼建議嗎?
P.S.評論的東西是我將需要的東西,但我已經能夠取出來簡化處理程序而不解決問題。它在那裏,不會被註釋,但它不是問題。
編輯︰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}
)
}
在這種情況下,順利,而throwError
掛在那兒。如果有人知道解決方案,請幫忙。