how to throw an error in a $http promise
Asked Answered
O

4

5

I have an angular service that wraps my rest api calls and returns a $http promise.

My question is how do I throw an error so that a promise that triggers the .error method gets called? I don't want to just throw error since I want it to use the .success/.error in the calling function rather than doing a try catch block around it.

myFunction: function(foo)
   if (foo) {
      return $http.put(rootUrl + '/bar', {foo: foo});
   }
   else {
      //what do I return here to trigger the .error promise in the calling function
   }
Omegaomelet answered 5/11, 2014 at 14:0 Comment(0)
O
0

First inject the $q-service in your service. Then in your else:

else {
     var deferred = $q.defer();
     deferred.reject("reject reason, foo was false");
     return deferred.promise;
}

Not as clever as Blazemonger's, but its quick to do.

Oscillation answered 5/11, 2014 at 14:15 Comment(3)
I get .success ... is not a function from the calling controller. do I have to define a success as well and just have it empty ?Omegaomelet
the promise returned have the normal then-function and also a catch-function. catch is short hand for then(null, errorcallback), which is i guess what you want. then is as you might know: then(success, error, notify)Oscillation
You can simply do $q.reject("reject reason, foo was false");, no reason to create the promise instance here.Bostow
L
6

You don't need $q.defer(). And else too. You can use reject directly:

myFunction: function(foo) {
    if (foo) {
        return $http.put(rootUrl + '/bar', {foo: foo});
    }

    return $q.reject("reject reason");
}

See https://docs.angularjs.org/api/ng/service/$q#reject

Lautrec answered 1/5, 2016 at 11:40 Comment(0)
B
1

You'll want to create your own promise using $q. Here's how I did something similar in a recent project:

app.service('allData', ['$http','$q',function($http,$q) {
    return {
        getJson: function() {
            return $q(function(resolve, reject) { // return a promise
                $http.get('/path/to/data.json', {cache:true})
                    .success(function(data) {
                        if (angular.isArray(data)) { // should be an ordered array
                        // or any other test you like that proves it's valid
                            resolve(data);
                        } else {
                            reject("Invalid JSON returned");
                            console.log(data);
                        };
                    })
                    .error(function(data) {
                        reject("Invalid data returned");
                        console.log(data);
                    });
            });
        }
    };
}]);

And in my controller:

allData.getJson().then(function(json) {
    // success, do something with the json
}, function(reason) { // failure, .getJson() had some kind of error
    alert('Sorry, unable to retrieve data from the server.')
    console.error(reason);
});
Blackleg answered 5/11, 2014 at 14:6 Comment(1)
if the controller is calling it via the convention .success().error() will it still work or would I need to define the success and error functions in the promise? is success.error() considered deprecated or legacy? should I switch to the .then() pattern?Omegaomelet
O
0

First inject the $q-service in your service. Then in your else:

else {
     var deferred = $q.defer();
     deferred.reject("reject reason, foo was false");
     return deferred.promise;
}

Not as clever as Blazemonger's, but its quick to do.

Oscillation answered 5/11, 2014 at 14:15 Comment(3)
I get .success ... is not a function from the calling controller. do I have to define a success as well and just have it empty ?Omegaomelet
the promise returned have the normal then-function and also a catch-function. catch is short hand for then(null, errorcallback), which is i guess what you want. then is as you might know: then(success, error, notify)Oscillation
You can simply do $q.reject("reject reason, foo was false");, no reason to create the promise instance here.Bostow
R
0

You can raise or throw a custom error using throw new Error ("custom error").

For http:

http.get('url').toPromise().then (result =>{
  throw new Error ("My Custom Error") // New Custom error  New is optional w
}).catch(err => {
  throw  err
}); // catch will catch any error occur while http call 
Revise answered 20/12, 2017 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.