EmberJS 404 Error Handling - ember.js

I'm dealing with error handling with EmberJS. Now I can handle my errors like this:
App.MediaShowRoute = Ember.Route.extend
...
actions:
error: ()->
#transitionTo '404'
But it is just a temporary decision. What I want to do now, is to render the '404' template within that route, where I get 404 error. For example, if I go to
/media/111111
route and i get an 404 error, I don't want to transition to the 404 page, I want to stay on the same page, but render the 404 template in it. I tried it this way:
actions:
error: () ->
#render '404',
into: 'media.show'
but it is not working :) I will be grateful for your help :)

You'll probably want to look at the ErrorRoute and error template here.
It doesn't exactly handle error codes very well, but when you reject the promise from the model on your App.MediaShowRoute your error will become the content of the ErrorController... You can then check for it in your ErrorRoute#renderTemplate
App.ErrorRoute = Ember.Route.extend({
'renderTemplate' : function() {
switch (this.get('controller.content.code')) {
case 404 : return this.render('404');
default : return this.render();
}
}
});
Take a look at my blog post for a more in depth example of how you might pass the error code around: http://www.riverrockapps.com/post/improving-error-route-in-emberjs

Related

Ember + Ember Data, Handling Error Substates at the Application Level, Ember 2.8

I'm trying to do something that sounds really simple. I want to render server errors to the outlet of my application.hbs.
Reading this doc, https://guides.emberjs.com/v2.6.0/routing/loading-and-error-substates/, I am able to detect my errors, but I can't seem to pass the error as a model to my error.hbs by following the given pattern.
If I register the error action handler on my application route as noted, I am able to render my error.hbs template, but I cannot access the context of the error object I'm dealing with. Additionally, my URL route updates, which is not desired.
actions: {
error(err, transition) {
return this.transitionTo('error');
}
}
Using this handler, I do render error.hbs to my outlet, but I don't get any context from my error object to render to that template. If I try to pass in the error as a model, I get this error:
More context objects were passed than there are dynamic segments for the route: error
Right now, whenever an error occurs loading a model, I just get a loading spinner state that hangs forever. I would like, instead, to display the server error(s).
Errors are passed to error substates as the model. The object that was thrown or rejected will be your error substate's model and its attributes will be the properties.
For example, if you throw or RSVP.reject { message: 'An Error Occurred' }, then you can display that in your error.hbs using {{model.message}}. I haven't ever seen throw/reject primitives work.
Here is a twiddle that demonstrates working error substates (load the /reject and /undefined routes to see additional examples).
Code from the twiddle
templates/application-error.hbs (could also be error.hbs)
<p>Application-Error Template</p>
<p>model: {{model}}</p>
<p>model.message: {{model.message}}</p>
<p>model.customMessage: {{model.customMessage}}</p>
routes/throw.js
model(params) {
throw { customMessage: 'Reject Error Message' };
},
routes/reject.js
model(params) {
return Ember.RSVP.reject({ customMessage: 'Reject Error Message' });
},
routes/undefined.js
model(params) {
use.undefined.value;
},

"Error while processing route" with unknown reason

My Goal: emulate nested route, but render it into application outlet.
For example:
/videos - top route
/videos/video001 - nested route
/videos/video001/slide001 - not nested. It is on the same level as /videos.
How I am doing this:
I have following router:
App.Router.map(function () {
this.resource('videos', { path: '/videos' }, function () {
this.resource('video', { path: '/:video_id' });
});
this.resource('slide', { path: '/videos/:video_id/:slide_id' });
});
To make 'slide' route work as expected I am overriding 'serialize' method, and
return 'video_id' and 'slide_id'
And at this point everything seems to be ok. At least page loads as expected.
What is the issue?
When I navigate to "/videos/video001" from "/videos/video001/slide001" via "link-to' helper,
I see following error: "Error while processing route: video".
And nothing more. I can't understand what kind of error happens and
why ember can't process route correctly. However I see that URL has been changed to "/videos/video001".
Any suggestions?
How to debug this situation or at least get any useful error message?
UPDATE
This article describe exact current situation and gives some solutions: http://hashrocket.com/blog/posts/ember-routing-the-when-and-why-of-nesting
Ok. I wasn't able to figure out what is the issue, and seems to be nobody able to help with that even on ember irc channel. So I have found interesting article http://hashrocket.com/blog/posts/ember-routing-the-when-and-why-of-nesting and implemented nesting via {into: 'application'}, but to make it work correctly i have overrided renderTemplate hook in all templates to define correct rendering order.
And everything works fine.
I do something similar but without the multiple IDs. Try this in your router:
this.resource('videos', { path: '/videos' }, function () {
this.resource('video', { path: '/:video_id' });
this.resource('videos.video.slide', { path: '/videos/:video_id/:slide_id' });
});
Your routes should be App.VideosRoute, App.VideosVideoRoute, and App.VideosVideoSlideRoute. Same for the controllers (if needed)

Error message logged when appending view for global loading state

I'm trying to have a default loading view. Following the information here: http://emberjs.com/guides/routing/loading-and-error-substates/#toc_legacy-code-loadingroute-code
LoadingView = Ember.View.extend({
templateName: 'global-loading',
elementId: 'global-loading'
});
ApplicationRoute = Ember.Route.extend({
actions: {
loading: function() {
var view = this.container.lookup('view:loading').append();
this.router.one('didTransition', view, 'destroy');
}
}
});
The view appears to be rendering but I get an error message logged to the console.
Uncaught TypeError: Cannot read property 'get' of null
It looks like it specifically has to do with callind ".append()"
Any idea whats wrong?
Marking this as answered.
It looks like this error was being triggered when the Chrome Ember Inspector was running. After I disabled the extension I didn't see the error message again. I think it was trying to get _debugContainerKey on an object that perhaps didn't have it.

Query-params-new nested routes strange error

In an application I use the latest canary versions for Ember and Ember Data. I have the following router:
this.resource('articles', {path: '/articles'}, function() {
this.resource('article', {path: '/:article_id'});
});
In the ArticlesController I specify some queryParams:
queryParams: ['category', 'search'],
category: '1', // defaults to 1
searchTerm: "",
In my ArticlesRoute I specify a model refresh and the model:
queryParams: {
category: {
refreshModel: true
}
},
model: function(params) {
// here I do use the params to return articles based on category and/or searchTerm
}
So far so good, all code above works perfect. However when I do a this.transitionTo('article', articleObject) or this.transitionToRoute('article', articleObject) in my application I get the following error:
Error: You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route article
at Object.__exports__.default.subclass.createParamHandlerInfo (http://localhost:8000/vendor/ember/index.js:44242:21)
at Object.__exports__.default.subclass.applyToHandlers (http://localhost:8000/vendor/ember/index.js:44121:37)
at Object.__exports__.default.subclass.applyToState (http://localhost:8000/vendor/ember/index.js:44088:21)
at Object.Router.transitionByIntent (http://localhost:8000/vendor/ember/index.js:43312:33)
at Object.Router.refresh (http://localhost:8000/vendor/ember/index.js:43459:21)
at EmberObject.extend.refresh (http://localhost:8000/vendor/ember/index.js:22616:35)
at EmberObject.extend._actions.queryParamsDidChange (http://localhost:8000/vendor/ember/index.js:22328:22)
at Object.triggerEvent (http://localhost:8000/vendor/ember/index.js:24563:38)
at trigger (http://localhost:8000/vendor/ember/index.js:44812:16)
at fireQueryParamDidChange (http://localhost:8000/vendor/ember/index.js:43612:9) index.js:14220
Uncaught Error: Assertion Failed: Error: You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route article index.js:3658
This strange error only happens when I first clicked a Category so the queryParam category is changed, and then fire a transitionTo to an article.
I have tried to use the debugger; statement to get the source of the error. However it seems that is an event that calls this error. When searching the sourcecode I found that the error originates from line 44242 of ember.js.
Does anyone know why this error happen after I have transitioned to a non query-params-new route?
Edit: now in Github too: https://github.com/emberjs/ember.js/issues/5070 (comment on Github)
JSBin: http://emberjs.jsbin.com/yiquyupa
I ran into almost the same issue in an afterModel callback where the parent route/controller has queryParams.
I found that if you just pass the queryParams from the transition argument (not the queryParams argument which is null/undefined) into Route.transitionTo / Route.replaceWith then the transition completes.
Example:
afterModel: function(model, transition, queryParams) {
// FIXME: unresolved Ember issue https://github.com/emberjs/ember.js/issues/5070
this.replaceWith('another.route', model, { queryParams: transition.queryParams});
}
I don't know why this happens, but queryParams is still a relatively new feature and still has some rough edges.

Transitioning when encountering an error in Ember

I am trying to do this.transitionTo('route name') in the ApplicationRoute error action.
What seems to happen is when I click on the link, it hits the error, and doesn't transition to the target route, it seems to say it's transitioning to the route it was just in again. This is using {{#link-to}} so I have a feeling there is some magic going on in there...
I am trying to use this example.
The error is happening in the model() method on the route (which is using jquery and returning a promise [jqXHR]) because I am returning a 401 http code.
Is this not correct?
App.ApplicationRoute = Ember.Route.extend(
actions:
error: (error, transition) ->
if error.status == 401
#transitionTo('login')
)
Another thing I've tried is setting the .ajaxError method and transitioning in there but the result seems to not transition either.
App.ApplicationRoute = Ember.Route.extend(
setupController: (controller, model) ->
route = #
Ember.$(document).ajaxError((event, jqXHR, ajaxSettings, error) ->
if jqXHR.status == 401
route.transitionTo('login')
)
controller.set('content', model)
)
Has anyone got this working on ember 1.2.0?
Try returning true in your error hook, to bubble the error event.
From the documentation (http://emberjs.com/guides/routing/asynchronous-routing/#toc_when-promises-reject):
actions: {
error: function(reason) {
alert(reason); // "FAIL"
// Can transition to another route here, e.g.
// this.transitionTo('index');
// Uncomment the line below to bubble this error event:
// return true;
}
}
Turns out it was an issue on my end. I had some extra logic that was essentially countering my transition! Whoops!