Dealing with errors in external URLs with AngularJS: A guide to intercepting errors in $resource or $http services

I have set up a separate server for my angularjs app, which is different from my grunt server. This external server runs on Apache and uses PHP to serve JSON data. I want to be able to catch any potential server errors, ranging from "server down" to "404".

I attempted to utilize interceptors in the following manner:

app.factory('myFactory', function($resource) {
  return $resource('http://www.remote.server.com/api/WRONGPATH',
});

app.config(function ($routeProvider, $httpProvider) {

  ...

  $httpProvider.responseInterceptors.push(function($q) {
    return function(promise) {
      return promise.then(function(successResponse) {
        if (successResponse.config.method.toUpperCase() !== 'GET') {
          console.info('success');
        }
        return successResponse;
      }, function(errorResponse) {
        switch (errorResponse.status) {
          case 401:
            console.info('wrong usename or password');
            break;
          case 403:
            console.info('no rights to do this');
            break;
          case 500:
            console.info('server internal error: ' + errorResponse.data);
            break;
          default:
            console.info('error ' + errorResponse.status + ': ' + errorResponse.data);
        }
        return $q.reject(errorResponse);
      });
    };
  });

});

Unfortunately, I was not successful with this approach as I always end up in the 'default' case, where errorResponse.status == 0.
I suspect that this is due to browsers stopping when encountering a CORS error...
However, everything works perfectly if I switch the remote URL to a local one...

Is there a way to handle errors from remote requests made by angular.js $resource (or $http)?

I am open to suggestions for a design change, such as restructuring my PHP service to work more like grunt... (currently, my PHP service simply outputs a JSON list of image names from a server folder...).

Answer №1

It seems that your interceptor is being placed in the wrong location. According to the $http documentation, you should be adding it to:

$httpProvider.interceptors

instead of:

// I've only seen this mentioned in outdated tutorials, so it may no longer be valid
$httpProvider.responseInterceptors 

Therefore, your code should look something like this:

$httpProvider.interceptors.push(function($q) {
  return {
    'response': function(response) {
      if (successResponse.config.method.toUpperCase() !== 'GET') {
        console.info('Success');
      }
      return response || $q.when(response);
    },
    'responseError': function(response) {
       switch (response.status) {
        case 401:
          console.info('Incorrect username or password');
          break;
        case 403:
          console.error('Unauthorized access');
          break;
        case 500:
          console.error('Internal server error: ' + response.data);
          break;
        default:
          console.error('Error ' + response.status + ': ' + response.data);
      }

      return $q.reject(response);
    }
  };
});

See the working example here on plnkr: here

Answer №2

It appears that the issue at hand is related to CSRF/XSRF protection rather than specific to AngularJS. Similar problems can arise in other frameworks or programming languages as well. For instance, in PHP, enabling CORS becomes necessary when accessing content across different domains, requiring you to specify which servers are allowed access.

To learn more about CORS and how to enable it, check out these resources: http://www.w3.org/wiki/CORS_Enabled http://enable-cors.org/server_php.html

In the case of AngularJS, the browser's response limitations affect the overall outcome, with unauthorized requests being blocked due to XSRF protection measures. When dealing with AngularJS and XSRF, the framework reads a token session cookie from the server and adds it to the HTTP header of subsequent requests. Ultimately, it is up to the server to determine whether to accept this token.

For more information on AngularJS $http service, visit: https://docs.angularjs.org/api/ng/service/$http

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Conceal a secret input element's value upon clicking a submit button (using PHP and jQuery)

Greetings, I'm facing an issue and need your assistance: Here's the scenario - I have a form that gathers First Name, Last Name, and City from the user. Upon clicking submit, the provided information is then showcased within a table as follows: ...

Targeting an HTML form to the top frame

Currently, I have a homepage set up with two frames. (Yes, I am aware it's a frame and not an iFrame, but unfortunately, I cannot make any changes to it at this point, so I am in need of a solution for my question.) <frameset rows="130pt,*" frameb ...

To ascertain whether the mouse is still lingering over the menu

I have a condensed menu construction that unfortunately cannot be changed in HTML, only CSS and JS modifications are possible! $('span').on("hover", handleHover('span')); function handleHover(e) { $(e).on({ mouse ...

Include a nested array of objects in the path

I'm looking to enhance the data visualization process by adding a path to the data before plotting the chart. Is there a way to retrieve a specific object by key, even if it's deeply nested, using recursion? I've attempted to do so, but my c ...

What are some strategies for stopping Knex.js from executing a query object upon return from an asynchronous function?

My node.js backend utilizes Knex.js to construct dynamic DB queries based on various inputs. The challenge I'm facing is handling asynchronous processing of certain inputs. When returning a knex query object from an async function or a Promise resolve ...

Editing the object retrieved from JSON is not possible once it has been fetched

Project. Input text in the field and it appears on the shirt. When you click "see back," there is an issue where new text overlaps old text. Clicking on "see front" allows you to enter new text, with the previous text saved underneath. Question: How can ...

Best practices for efficiently utilizing setInterval with multiple HTTP requests in NodeJS

Imagine you have a collection with 3 to 5 URLs. You want to send requests every 5 seconds, one by one. Here is how I approached this: setInterval(() => { array.forEach(element => { request .get(element.url) .on('response', ...

Guide for creating a smooth fade in/out effect for the "Show More" feature in Vue

This is my current Lorem Ipsum page. When I click the Lorem button, the text will be expand or collapse. https://i.sstatic.net/BldW4.png I attempted to modify the css below to create a fading effect for the hidden text. @keyframes open { from { li ...

looping through the multi-dimensional array using v-for

Interested in using v-for and I have encountered a scenario with an object structure as seen here: https://i.sstatic.net/wNguk.png Upon inspecting the dev console, the object looks similar to this: https://i.sstatic.net/jyqth.png My query is about how to ...

Tips for customizing the border radius style of the menu in Vuetify's v-autocomplete component

I am looking to customize the appearance of the drop-down list in the v-autocomplete component by adding a border-radius style, as depicted in the image below. The current design I have achieved closely resembles the visual shown below. Previously, I app ...

Ways to automatically refresh a page in Javascript after a short period of user inactivity

Similar Question: How Can I Modify This Code To Redirect Only When There Is No Mouse Movement I am looking to update a web page automatically if the user is inactive, specifically through key presses or mouse clicks using Javascript. ...

What are the steps for importing KnockOut 4 in TypeScript?

It appears straightforward since the same code functions well in a simple JS file and provides autocompletion for the ko variable's members. Here is the TypeScript code snippet: // both of the following import lines result in: `ko` undefined // impo ...

If $urlRouterProvider.otherwise is used, $stateProvider will not handle the routing

Previously, when "/" was set as "/main", the code was able to load both main and dashboard using $urlRouterProvider.otherwise("/main/dashboard"); However, after changing it to just "/", the dashboard does not load anymore. This change was made due to an i ...

Utilizing styled-components or personalized components alongside cypress

Cypress selector made simple: just use cy.get('.myComp') and it will select <input className="myComp" />. But when it comes to styled-components... Perhaps we have to resort to using custom attributes like cy-data or cy-testid. Sadly, it s ...

The Facebook Like Button appears on Firefox but not on Internet Explorer due to Javascript errors

Hello everyone, I could really use some help with an issue I am facing. My Facebook like button works perfectly fine in Firefox, but when it comes to Internet Explorer, I keep encountering Javascript errors and the button doesn't show up at all: If y ...

"Process the contents of a file by reading it line by line in a

Currently, I am reviewing the documentation for the nodejs readline module in order to tackle a task that involves reading a very large file line by line. The solution using readline seems promising, although I require it to read lines synchronously - mean ...

Is it possible to create Firebase real-time database triggers in files other than index.js?

Is it possible to split a large index.js file into multiple files in order to better organize the code? Specifically, can Firebase triggers be written in separate JavaScript files? If so, could you please provide guidance on how to do this properly? child. ...

What are the steps to run and test the renovate bot on your local machine

Before setting up renovate to work with my Azure pipeline, I wanted to test it locally using npx renovate to ensure everything is working as expected and that my config file is properly configured. I ran npx renovate --platform local command. My project i ...

What is the ideal event to trigger a response when the user completes entering text into the search field in Vue.js?

I am currently utilizing a text field from the Vuetify library to filter a table within my application. <v-text-field style="min-width: 300px;" v-model="filterString" label="Search" /> The functionality is straigh ...

The back-end code on the server is unable to identify the variable in my req.body, as it is being flagged

At the moment, I am in the process of developing a web application that needs to transmit data from the client side to the server side whenever a specific button is clicked. However, when I click the button, the terminal consistently informs me that the va ...