2016-02-06 27 views
24

Làm thế nào để báo cho Angular không chặn toàn bộ ứng dụng khi nó gặp phải một ngoại lệ?Angular2: Ứng dụng bị treo/không phản ứng sau khi gặp phải một ngoại lệ/lỗi

Tôi không chắc liệu điều đó có thể xảy ra hay không vì Google không khai sáng cho tôi về điều này. Nhưng nó có vẻ quan trọng đối với bất kỳ ứng dụng web trang đơn nào.

Góc là nhanh và tất cả trừ khi gặp phải ngoại lệ và ném lỗi, ứng dụng hoàn chỉnh trở nên không phản hồi.

Tôi biết rằng trong Javascript

try { 
    doSomething(); 
} 
catch(err) { 
    handleErrors(err); 
} 

có thể giải quyết vấn đề.

Nhưng tôi chỉ muốn biết liệu có bất kỳ giải pháp hoặc giải pháp cụ thể nào của Góc không?

+0

http://stackoverflow.com/questions/37836172/angular-2-doesnt-update-view-after-exception-is-thrown#answer-43796615 – yurzui

Trả lời

12

Trên phiên bản cuối cùng 2 góc cạnh, bạn có thể triển khai tùy chỉnh ErrorHandler.

Example From Angular docs:

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

class MyErrorHandler implements ErrorHandler { 
    handleError(error) { 
    // do something with the exception 
    } 
} 

@NgModule({ 
    providers: [{provide: ErrorHandler, useClass: MyErrorHandler}] 
}) 
class MyModule {} 
8

cập nhật 2.0.0 RC.6 thay đổi tên từ ExceptionHandler để ErrorHandlercall để handleError

@Injectable() 
class MyErrorHandler implements ErrorHandler { 

    handleError(error) { 
    // do something with the exception 
    } 
} 


@NgModule({ 
    directives: [MyApp], 
    providers: [ 
    {provide: ErrorHandler, useClass: MyErrorHandler} 
    ] 
}) 
export class AppModule {} 

Xem thêm https://angular.io/docs/ts/latest/api/core/index/ErrorHandler-class.html

gốc

Thực hiện một handler tùy chỉnh ngoại lệ https://angular.io/docs/ts/latest/api/core/ExceptionHandler-class.html

@Injectable() 
class MyExceptionHandler implements ExceptionHandler { 
    call(error, stackTrace = null, reason = null) { 
    // do something with the exception 
    } 
} 


@NgModule({ 
    directives: [MyApp], 
    providers: [ 
    {provide: ExceptionHandler, useClass: MyExceptionHandler} 
    ] 
}) 
export class AppModule {} 

cũng Xem https://github.com/angular/angular/issues/6865https://github.com/angular/angular/issues/6565

tôi đã không cố gắng bản thân mình nếu điều này cho phép các ứng dụng để tiếp tục sau khi một ngoại lệ nhưng tôi nghĩ rằng nó có giá trị một thử. Ít nhất phải tải lại trang tự động.

Nói chung, ngoại lệ phải được xử lý càng gần càng tốt với nguyên nhân khi có cách khôi phục.

+3

Tôi đã thử nó và thành công được chuyển hướng đến trang chủ không dễ bị lỗi, tốt hơn là không có gì. Nhưng tôi đã không tìm thấy một cách để cho các ứng dụng ở lại đáp ứng ngay cả sau khi ngoại lệ, mà nói chung sẽ không phải là một cách tốt nhưng là một dự phòng nó có thể là tốt đẹp để có. –

+0

Tôi đoán không có cách nào khác hơn là bắt ngoại lệ trước đó. Các bong bóng ngoại lệ lên đến Góc và Góc không có cách nào để biết cách xử lý "lỗi" tùy chỉnh của bạn. Nó chạy xử lý ngoại lệ của bạn và thoát. –

+0

Vâng, nếu đúng như vậy. Tôi không biết liệu tôi có nên chấp nhận câu trả lời để giúp đỡ người khác, vì tôi không quen thuộc với các quy tắc SO. BTW để làm cho giải pháp làm việc nó cần một số chỉnh sửa, mà tôi sẽ. –

3

Tôi cố gắng để thực hiện chỉnh Exception Handler theo chỉ dẫn của @ GünterZöchbauer

và điều này làm việc cho tôi


Bootstrap ứng dụng của bạn với CustomExceptionHandler.

import {ExceptionHandler} from 'angular2/core'; 

class _ArrayLogger { 
    res = []; 

    log(s:any):void { 
    this.res.push(s); 
    } 
    logError(s:any):void { 
    this.res.push(s); 
    } 
    logGroup(s:any):void { 
    this.res.push(s); 
    } 
    logGroupEnd() { 
    if(this.res.length) { 

     //this section executes if any error is logged by angular. 

     //do your stuff here 

     /*e.g 

     if(location.pathname !== 'dashboard') { 
      window.location.href = '/dashboard'; // condition is required to prevent infinite loop 
     } 

     */ 
    } 
    }; 
} 

export class CustomExceptionHandler extends ExceptionHandler { 
    constructor() { 
    super(new _ArrayLogger(), true); 
    } 

    call(error, stackTrace = null, reason = null) { 
    super.call(error, stackTrace, reason); 
    } 
} 

bootstrap(MyApp, [provide(ExceptionHandler, {useClass: CustomExceptionHandler})]) 
+0

Tôi cho rằng bạn vẫn phải tải lại tất cả các thành phần. Bạn đã thử chưa –

+1

có, trong 'logGroupEnd() {if (this.res.length) {' Tôi đã làm 'window.location.href = '/'' hoặc một số đường dẫn defaullt khác –

+1

Ankit, @ GünterZöchbauer Tôi cũng phải đối mặt với cùng một loại vấn đề. Nhưng, tôi nghĩ rằng đây không phải là một giải pháp tốt vì nếu một người dùng đang sử dụng spa và đột nhiên một số trường hợp ngoại lệ js đến, sau đó trang được tải lại và chuyển hướng đến một số trang khác. Người dùng sẽ không thể hiểu điều gì đang xảy ra. Vì vậy, bạn đã tìm thấy bất kỳ cách nào khác xung quanh? – monica

2

Tôi nghĩ vấn đề có thể xảy ra khi bạn đang sử dụng RxJS quan sát, mà bỏ đăng ký khi họ gặp phải bất kỳ lỗi. Nếu đó là trường hợp của bạn, bạn có thể cần phải:

  1. Săn ngoại lệ trong onNext xử lý sự 's .subscribe với try...catch thay vì bên onError xử lý.
  2. Đăng ký lại trong bộ xử lý onError của .subscribe.
+0

Cách truy cập trình xử lý này trên trình xử lý tiếp theo. Bạn có thể xây dựng cú pháp? – jackOfAll

+0

@jackOfAll Sure. Khi bạn có một đối tượng quan sát được, thì bạn có thể gọi phương thức 'subscribe' trên nó, tức là:' observable.subscribe (myHandler) '. Phương thức 'subscribe' thực sự lấy 3 đối số. Cái đầu tiên được gọi là 'onNext', thứ 2 -' onError' và thứ 3 - 'onCompleted'. Bạn có thể xem thêm tại đây: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/subscribe.md. Đừng ngần ngại hỏi nếu bạn có thêm bất kỳ câu hỏi nào hoặc nếu câu trả lời của tôi không đề cập đến ý của bạn :) –

+0

Cảm ơn Michal. Tôi đã thử gói toàn bộ phương thức đăng ký trong một khối try try. Tôi cũng đã thử đặt mã với mỗi đối số gọi lại (onNext và onError, tôi chưa khám phá onCompleted) trong các khối try catch. Nhưng trong mỗi trường hợp tôi không thể bắt được ngoại lệ! Trong trường hợp của tôi vụ tai nạn xảy ra khi tôi nhận được phản hồi 404 từ API của tôi và tôi kết thúc trong cuộc gọi lại onError – jackOfAll

Các vấn đề liên quan