2015-06-03 9 views
10

Próbuję złapać 404 błędy w mojej aplikacji ember i przekierować do /not-found.EmberJS/Ember Data: 404 nie zostaje złapany

Mam akcję errors na moim ApplicationController i mam też funkcję RSVP.on('error'), ale 404-te nie zostają złapane. Właśnie dostaję błąd 404 do konsoli z jQuery, ale błąd nie jest przekazywany do obsługi błędu.

Console Error

Błędy Inicjator:

import Ember from 'ember'; 

var initialize = function(container) { 
    var errorReporting = container.lookup("service:errorReporting"); 

    Ember.RSVP.on('error', function(err) { 
    Ember.warn("Ember.RSVP error..... Logging error:"); 
    console.log(err); 
    if (err.name && err.name === 'TransitionAborted') { 
     Ember.debug("TransitionAborted error. Doesn't look like we should be catching these."); 
    } else { 
     container.lookup('route:application').send('error', err); 
    } 
    }); 

    window.onerror = function(err) { // window general errors. 
    Ember.warn("Uncaught error (tripped window.onerror)..... Logging error:"); 
    console.log(err); 
    errorReporting.report(err); 
    }; 

}; 

export default { 
    name: 'errors', 
    initialize: initialize 
}; 

Akcja błąd na moim applicationRoute jest ogromny (i mogę go zakładać), ale nawet nie wydają się być wywołana coraz.

EDIT 1: Kod Trasa

import Ember from 'ember'; 
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin'; 

export default Ember.Route.extend(AuthenticatedRouteMixin, { 

    titleToken: function(model) { 
    return model.get('name'); 
    }, 

    model: function(params) { 
    return this.store.find('location', params.location_id); 
    } 

}); 

EDIT 2: ApplicationRoute/obsługi błędów

error: function(err, transition) { 
     if (!Ember.isNone(transition)) { 
     transition.abort(); 
     } 

     let errorHolder = this._getErrorDataFrom(err); 
     let errorMessage = this._getErrorMessageFrom(errorHolder); 
     let isFourOhFour = (typeof(err.status) !== 'undefined' && err.status === 404) || errorHolder.reason === 'not_found'; 

     if (isFourOhFour) { 
     return this.transitionTo('not-found'); 
     } 

     let requireAuthentication = (errorHolder.reason === 'not_authenticated'); 
     if (requireAuthentication) { 
     window.localStorage.setItem('toast-on-reload', errorHolder.message); 
     return this.session.invalidate(); 
     } 

     let isValidationError = (errorHolder.reason === "validation_error" || 
           (!Ember.isNone(errorHolder.errors) && !Ember.isNone(errorHolder.message))); 
     if (isValidationError) { 
     this.toast.error(errorMessage); 
     return; 
     } 

     let verificationRequired = (errorHolder.reason === "verification"); 
     if (verificationRequired) { 
     this.toast.error(errorMessage); 
     return this.transitionTo('verification'); 
     } 

     let invalidRequest = (errorHolder.reason === 'unprocessable_entity'); 
     if (invalidRequest) { 
     this.toast.error(errorMessage); 
     return; 
     } 

     this.errorReporting.report(errorHolder); 
     this.toast.error(errorMessage); 
     return this.transitionTo('error'); 
    } 
    }, 

    _getErrorDataFrom: function(obj) { 
    if (!Ember.isNone(obj.responseJSON)) { 
     return obj.responseJSON; 
    } else if (!Ember.isNone(obj.success) || !Ember.isNone(obj.errors)) { 
     return obj; 
    } else if (!Ember.isNone(obj.jqXHR) && !Ember.isNone(obj.jqXHR.responseJSON)) { 
     return obj.jqXHR.responseJSON; 
    } else { 
     Ember.warn("No error handler available, using default ({}). Error:"); 
     console.log(obj); 
     return {}; 
    } 
    }, 

    _getErrorMessageFrom: function(errorHolder) { 
    if (typeof(errorHolder.errors) === 'object' && !Ember.isNone(errorHolder.errors.message)) { 
     return errorHolder.errors.message; 
    } else if (!Ember.isNone(errorHolder.errors)) { 
     return errorHolder.errors; 
    } else if (!Ember.isNone(errorHolder.message)) { 
     return errorHolder.message; 
    } else { 
     return "Sorry, something went wrong."; 
    } 
    } 
+0

Jak się nazywasz 'operatory/lokalizacja/to-nie-istnieje? – Kingpin2k

+0

@ Kingpin2k W tym szczególnym przypadku odwiedzam tylko trasę 'myapp.com/locations/this-does-not-exist'. 'operatory /' to przestrzeń nazw interfejsu API. – Brandon

+0

Zwiedzanie jak podczas wpisywania adresu URL w pasku adresu? – Kingpin2k

Odpowiedz

11

Jeśli chcesz użyć zdarzenia error, a następnie umieścić jego obsługi wewnątrz actions hash na trasie aplikacji.

Można również rozważyć użycie trasy błędu. Możesz to zdefiniować w pods/application/error, z szablonami, trasami i kontrolerami, jak każda inna trasa. Zobacz http://guides.emberjs.com/v1.10.0/routing/loading-and-error-substates/#toc_code-error-code-substates. Kod błędu zostanie przekazany do tej trasy błędu jako jego model.

Wreszcie, w wielu przypadkach jest najprostszy i najbardziej niezawodny w przypadku błędu .

model: function(params, transition) { 
    return this.store.find('location', params.location_id) . 
     catch(err => this.send('ajaxError', err)); 
} 

Następnie zdefiniować akcję ajaxError na trasie aplikacji, która robi to samo rodzaju rzeczy robisz w swoim hakiem error teraz. Jednak spowoduje to uchwycenie tylko błędów ajax, a nie innych rodzajów błędów, które mogą wystąpić podczas przejścia i zostanie połknięta (lub w twoim przypadku zgłoszona przez Ember.RSVP.on('error').

+0

Dzięki @torazaburo. To jest prawdopodobnie to, czego szukam. Naprawdę miałem nadzieję, że wymyślę sposób, w jaki mogę zwrócić "humanizowane" komunikaty o błędach z API na klucz 'error' w odpowiedzi JSON i mam do czynienia we wszystkich przypadkach. – Brandon

Powiązane problemy