Intercepting error handling with loopback - loopbackjs

Is there somewhere complete, consistent and well documented source of information on error handling in loopback?
Things like error codes and their meaning, relation with http statuses. I've already read their docs and have not found anything like this.
I would like to translate all the messages to add multi language support to my app. I would also like to add my custom messages, with their code and to use it consistently with other loopback errors.
In order to achieve this, I need to intercept all the errors (I've done this already) and to know all the possible different codes, so I can translate them.
For example, if there is an error with code 555, I have to know what it means and treat it accordingly.
Any ideas?

I need to "catch" all the messages and translate them
This is the beginning of an answer. You can write an error-handling middleware that will intercept any error returned by the server. You will need in turn to implement the logic for making the translation.
module.exports = function() {
return function logError(err, req, res, next) {
if (err) {
console.log('ERR', req.url, err);
}
next();
};
};
This middleware must be configured to be called in the final phase. Save the code above in log-error.js for instance, then modify server/middleware.json
{ "final": { "./middleware/log-error": {} } }
I need a full list of loopback codes/messages
I'm pretty sure there is no such thing. Errors are build and returned all over the place in the code, not centralized anywhere.

Related

Apollo iOS how to handle partial decoding failure

I'm trying to see if there is a way to do more robust handling of partial decoding failures of Apollo generated Swift classes. Currently, if even one field of one object in an array fails to parse from the network response, the entire collection of objects fails to parse and our iOS client gets no data.
Our graphql is defined something like:
query mobile_getCollections() {
getCollections() {
// ... other fields
items {
activeRange {
expires // Int!
starts // Int!
}
}
}
}
So the Apollo generated Swift code is expecting non-nil Ints when decoding these values. However, due to a backend error (that we would like to make the mobile clients more resilient to), the API will occasionally send us a malformed date String instead of a unix timestamp Int. This causes parsing of the entire mobile_getCollections result to fail, because the Apollo generated query class typing can't be perfectly satisfied.
Ideally, I'd like to just throw out the one item in the collection that failed to be parsed correctly and leave the remaining items intact. Is it possible to do something like that using Apollo?
(Yes, I know the real answer here is to fix the backend, but is there anything I can do in the mean time to more gracefully handle similar partial parsing failure issues?)

loopback operation hook: add filter to count api

I need to intercept my loopback queries before they query my Mongodb to add additional filters, for example, to limit the object to what the user has access to.
I can successfully update the query on access operation hook to add filters to the GET /Applications , where Applications is my object. However This fails to work for GET /Applications/count
The command runs with a 200, however it returns zero results, even though I'm adding the exact same filters. There most be something different about count that I'm missing. The ctx object looks have a ton of functions/objects in it. I'm only touching the query property, but there must be something else I need to do.
Any ideas? Thank you, Dan
Could you please share your access hook observer's implementation. I tried it on a sample app, and following access hook works as expected for /api/Books/count:
module.exports = function(Book) {
Book.observe('access', function logQuery(ctx, next) {
ctx.query.where.id = 2; // changing filter value for where
console.log('Accessing %s matching %j', ctx.Model.modelName, ctx.query.where);
next();
});
};
Verify that you're modifying query property of Context (see access hook).
Hope that helps.

Dynamic messages with gettext (AngularJS)

I have a application with a Django backend and an AngularJS front-end.
I use the angular-gettext plugin along with Grunt to handle translations.
The thing is, I sometimes received dynamic strings from my backend through the API. For instance a MySQL error about a foreign key constraint or duplicate key entry.
How can I add this strings to the .pot file or non harcoded string in general ?
I've tried to following but of course it cannot work :
angular.module('app').factory('HttpInterceptor', ['$q', '$injector', '$rootScope', '$cookieStore', 'gettext', function ($q, $injector, $rootScope, $cookieStore, gettext) {
responseError: function (rejection) {
gettext('static string'); //it works
gettext(rejection.data.error); //does not work
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
})();
One solution I could think of would be to write every dynamic strings into a JSON object. Send this json to server and from there, write a static file containing these strings so gettext can extract them.
What do you suggest ?
I also use angular-gettext and have strings returned from the server that need to be translated. We did not like the idea of having a separate translation system for those messages so we send them over in the default language like normal.
To allow this to work we did two things. We created a function in our backend which we can call to retrieve all the possible strings to translate. In our case it's mainly static data that only changes once in a while. Ideally this would be automated but it's fine for now.
That list is formatted properly through code into html with the translate tag. This file is not deployed, it is just there to allow the extraction task to find the strings.
Secondly we created a filter to do the translation on the interpolated value, so instead of translating {{foo}} it will translate the word bar if that's was the value of foo. We called this postTranslate and it's a simple:
angular
.module('app')
.filter('postTranslate', ['gettextCatalog', function (gettextCatalog) {
return function (s) {
return gettextCatalog.getString(s);
};
}]);
As for things that are not in the database we have another file for those where we manually put them in. So your error messages may go here.
If errors are all you are worried about though, you may rather consider not showing all the error messages directly and instead determine what user friendly error message to show. That user friendly error message is in the front end and therefore circumvents all of this other headache :)

Ember.js - What purpose does Ember.lookup serve

Can anyone tell me what purpose Ember.lookup serves?
It is used to lookup string keys.
An example of its use in the ember source is:
if(typeof modelType === "string"){
return Ember.get(Ember.lookup, modelType);
} else {
return modelType;
}
I can see that it returns a type from a string but I don't see where it is set or what the bigger picture is for its usage.
Ember.lookup was introduced along with Ember.imports and Ember.exports as a way to remove the dependency on window.
If you are running Ember in the browser, all three values will refer to the window, however if you are running without the browser, for instance, through NodeJS or with AMD, you will need to supply values yourself.
See the commit message for more information.

Ember.js router events as functions not working

I have set up some basic routing in my app by using the examples at http://emberjs.com/guides/outlets/#toc_the-router
Within the root I have some events that trigger from view actions e.g:
gotoStepOne: Ember.Route.transitionTo('stepOne'),
gotoStepTwo: Ember.Route.transitionTo('stepTwo'),
gotoStepThree: Ember.Route.transitionTo('stepThree'),
gotoStepFour: Ember.Route.transitionTo('stepFour'),
gotoStepFive: Ember.Route.transitionTo('stepFive'),
Full example router code at http://jsfiddle.net/hellosmithy/WdjXT/
This all works fine at the moment. The problem is that I'd like to add other code into these events. For example:
gotoStepOne: function() {
if (someCondition) {
Ember.Route.transitionTo('stepOne');
}
someOtherFunction();
}
However doing this breaks the routing without throwing any errors. It just no longer transitions.
Specifically I only want transitions to happen if a certain state is met - something has been selected or input by the user at each stage before they can proceed. Is there a workaround for this, or should I be abstracting this functionality elsewhere?
The way I understand the router is, that it is the representation of the application's state.
Specifically I only want transitions to happen if a certain state is met - something has been selected or input by the user at each stage before they can proceed.
So the user inputting or selecting something puts your application in a certain state which is reflected by the router.
IMHO it should be something like this in a view (or controller):
userDidSomething: function(condition) {
if (condition) {
App.get('router').send('stepOne');
}else{
someOtherFunction();
}
}