0

I have a server api that returns a json string like {status: ok/error, errtext: ..., payload: ...}. When status !== 'ok' I would like my program to take the error handling method, the equivalent of $q.reject. I am using http transform to harmonize some of my data structures.

My code:

var p = $http({
            url: url,
            timeout: cancel.cancel,
            method: 'GET',
            headers: addl_headers,
            transformResponse: _appendTransform($http.defaults.transformResponse, function (data, headers, status) {
                return _doTransform(data, headers, status);
            })
        });
p.then(function(goodrespObj){...}, function(badnessObj){...});

And

    function _appendTransform(defaults, transform) {
        defaults = angular.isArray(defaults) ? defaults : [defaults];
        return defaults.concat(transform);
    }
    function _doTransform(data, headers, status) {
        if (data.status !== 'OK') {
            console.error("bad errtext", data.status, "$http status", status);
            (X) ????? something smart that will trigger HTTP ERROR path ?????
        }
        // ...
        return f(data); // this is received as "goodrespObj.data" above
    }

If at the point marked (X) if I return the error text, it comes back verbatim to "good" function. How do I indicate a server error, or somehow cause the $q.reject(resp) path in transformResponse?

Looking at the code for transformResponse() I can see that user function has no way to touch response.status so is there another way?

I am using angular with ionicframework.

edit: removed my previous comment - see the accepted answer.

Dinesh
  • 4,437
  • 5
  • 40
  • 77
  • 1
    Have you looked at adding a response interceptor? You should be able to examine the JSON in all responses, and turn them into rejections before they ever hit your controller. Have a look at the accepted answer here: http://stackoverflow.com/questions/11956827/angularjs-intercept-all-http-json-responses – Alan Jun 17 '15 at 23:00

1 Answers1

2

transformResponse is usually used for transforming the response from another format (or similar purposes).

What you are looking for is intercept.

$httpProvider.interceptors.push(function($q) {
  return { 
    'response': function(response) {
       if (isBad(response)) {
           return $q.reject(rejectionReason(response));
       }
    }
  };
});
Umur Kontacı
  • 35,403
  • 8
  • 73
  • 96
  • I frequently want to do something similar but end up treating http and server errors separately from logic error. Is this approach a normal practise? – Joao Leal Jun 17 '15 at 23:03
  • 1
    Yes. HTTP errors can be caused from a bad request, bad connection, expired session, down servers etc. You should handle them properly and show some information to the user to try again later (you can also retry in the code). Logic errors are caused by the developers and are bugs in the code. They should fail fast, throw errors so you notice it right away and fix it. PS: This is somewhat irrelevant to the context and it is better if you would create a new question to ask this. – Umur Kontacı Jun 17 '15 at 23:10
  • @UmurKontacı but I have to do a `throw`, not `$q.reject`. With reject, it still takes the good response path. – Dinesh Jun 18 '15 at 00:49
  • @Dinesh You don't need to throw, you need to return the result of `$q.reject`. (I did update the code example) – Umur Kontacı Jun 18 '15 at 07:59
  • @UmurKontacı thanks!! I also found out that the $q.reject call parameter becomes the error handler's argument, so I need to do something like e.g. `{response.statusText = 'bad!'; return $q.reject(response);}` – Dinesh Jun 18 '15 at 17:37