2016-02-06 18 views
24

Jak poinformować Angular, aby nie blokował całej aplikacji, gdy napotka wyjątek?Angular2: Aplikacja ulega awarii/przestaje reagować po napotkaniu wyjątku/błędu

Nie jestem pewien, czy jest to możliwe, ponieważ google mnie o tym nie poinformował. Ale wydaje się krytyczne dla każdej aplikacji internetowej strony.

Kątowy jest szybki i zawsze, gdy napotka wyjątek i zgłasza błąd, kompletna aplikacja przestaje odpowiadać.

wiem, że w JavaScript

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

może rozwiązać ten problem.

Ale chcę tylko wiedzieć, czy istnieje jakieś konkretne rozwiązanie lub obejście Angular?

+0

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

Odpowiedz

12

W wersji kątowej 2 wersji ostatecznej można zaimplementować niestandardową 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

aktualizacja 2.0.0 RC.6 zmienił nazwę z ExceptionHandler do ErrorHandler i call do handleError

@Injectable() 
class MyErrorHandler implements ErrorHandler { 

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


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

Patrz także https://angular.io/docs/ts/latest/api/core/index/ErrorHandler-class.html

oryginalny

Wdrożenie inny system obsługi wyjątków 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 {} 

Zobacz także https://github.com/angular/angular/issues/6865 i https://github.com/angular/angular/issues/6565

nie próbowałem się, czy ten umożliwia aplikację, aby kontynuować po drodze wyjątku, ale myślę, że warto spróbować. Przynajmniej ponowne załadowanie strony powinno być możliwe.

Zasadniczo wyjątek należy traktować tak blisko, jak to możliwe, gdy istnieje sposób na odzyskanie.

+3

ja spróbowałem i skutecznie przekierowany na stronę bez błędów, która jest lepsza niż nic. Ale nie znalazłem sposobu, aby aplikacja pozostała responsywna nawet po wyjściu z wyjątku, , co ogólnie nie byłoby dobrym pomysłem, ale może być przyjemne. –

+0

Chyba nie ma innego sposobu niż wychwycenie wyjątku wcześniej. Bąbelki wyjątków do Angular i Angular nie mają możliwości sprawdzenia, jak radzić sobie z niestandardowym "błędem". Uruchomi twój program obsługi wyjątków i kończy działanie. –

+0

Cóż, jeśli tak jest. Nie wiem, czy powinienem przyjąć odpowiedź, by pomóc innym, ponieważ nie bardzo znam zasady SO. Przy okazji, aby rozwiązanie działało, wymaga edycji, co zrobię. –

3

starałem się wdrożyć niestandardowy Exception Handler jako reżyserii @ GünterZöchbauer

i ten pracował dla mnie


Bootstrap aplikacji z 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

Zakładam, że nadal musisz przeładować wszystkie komponenty. Czy próbowałeś? –

+1

tak, w 'logGroupEnd() {if (this.res.length) {' Mam do zrobienia 'window.location.href = '/'' lub innej ścieżki defaullt –

+1

Ankit, @ GünterZöchbauer Mam również do czynienia z ten sam rodzaj problemu. Ale myślę, że to nie jest dobre rozwiązanie, ponieważ jeśli użytkownik korzysta ze spa i nagle przychodzą wyjątki js, to strona zostaje przeładowana i przekierowana na inną stronę. Użytkownik nie będzie w stanie zrozumieć, co się dzieje. Więc znalazłeś coś innego? – monica

2

Myślę, że problem może wystąpić, jeśli używasz RxJS obserwabli, który wypisania gdy napotkają żadnych błędów. Jeśli tak jest w Twoim przypadku, może zajść potrzeba:

  1. połowu wyjątek w ramach .subscribe „s onNext obsługi z try...catch zamiast wewnątrz onError obsługi.
  2. Ponownie zasubskrybuj w .subscribe opiekun
+0

Jak uzyskać dostęp do funkcji obsługiNext. Czy mógłbyś rozwinąć składnię? – jackOfAll

+0

@jackOfAll Pewnie. Kiedy masz obiekt obserwowalny, możesz wywołać na nim metodę "subscribe", tzn .: 'obserwowalna wartość zapisu (myHandler)'. Metoda "subscribe" faktycznie przyjmuje 3 argumenty. Pierwszy nazywa się 'onNext', 2nd -' onError' i 3rd - 'onCompleted'. Możesz zobaczyć więcej tutaj: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/subscribe.md. Nie wahaj się zapytać, czy masz więcej pytań lub czy moja odpowiedź nie dotyczy tego, co masz na myśli :) –

+0

Dzięki Michał. Próbowałem owijać całą metodę subskrypcji w bloku catch catch. Próbowałem również umieścić kod z każdym argumentem wywołania zwrotnego (onNext i onError, nie badałem onCompleted) w blokach catch catch. Ale w każdym przypadku nie mogłem złapać wyjątku! W moim przypadku katastrofa ma miejsce, gdy otrzymuję odpowiedź 404 z mojego interfejsu API i kończę w wywołaniu zwrotnym onError – jackOfAll

Powiązane problemy