2

I have an Angular frontend, and a .NET CORE backend. I have one particular request which is quite heavy and takes a while to execute. When I look in the browser console, I get a 504: Timeout while reading response from the server.

The backend finishes the request, I can see in the logging it returns some JSON after a certain amount of time (somewhere after I get the time out).

First I tried adding a timeout header to the angular request as follows:

    const options = { headers: new HttpHeaders({ timeout: `${10000}` }) };

This didn't work.

I also tried to add the function in my rxjs pipe.

 this.service.getData(this.id, this.codeSystem, this.code)
    .pipe(
      timeout(120000),
      map(data=> {
       this.data = data;
      }),
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
      }))
    .subscribe();

After that I tried to increase the Connection Timeout under advanced settings in IIS, this also didn't work.

At this point I'm not sure where the problem is located or how to solve it. Does anyone have an idea/suggestion?

BartKrul
  • 577
  • 1
  • 8
  • 21

3 Answers3

3

The problem is located on the server. There is nothing you can do from the browser. Most browsers will disconnect on their own if the server does not send a response within a time limit, and we can't change this from JavaScript for security reasons. The server must send partial body content in response to the request to continue the connection. As long as the server is busy it must send something to persist the connection.

If you have an API that takes a long time to complete and you see disconnections as a result, then you should give up on expecting to get the JSON response.

Contact the author of the API and ask them nicely to fix their server.

When making a request that takes a lengthly time to complete. The best practice is to POST to start a service and the server responds with a task ID. You then GET status updates on that task ID on intervals until the status of the task ID reports what happened. You can then request the server to send the client the output from the task.

In the meantime, make the request and ignore errors. You can't fix this problem from the browser.

Reactgular
  • 52,335
  • 19
  • 158
  • 208
  • Thanks, I'll try this. I didn't know this was a thing! What exactly are the security reasons behind this not being possible? I can imagine it could crash the browser, but there's multiple ways to do that. – BartKrul Jun 17 '19 at 14:26
0

You don't need timeout. You can set take or takeUntil so that your subscription is "hot" until you get a response.

callEndpoint() {
    this.service.getData.pipe(
       take(1) // wait for response
    ).subscribe( (user: User) => {
       console.log(user); // make sure you're getting a response from dataService
    });
}

Also, check that the endpoint is getting the data it expects: this.id, this.codeSystem, this.code

Ben Racicot
  • 5,332
  • 12
  • 66
  • 130
  • doesn't takeWhile do the same thing? That's already included in the code. – BartKrul Jun 13 '19 at 06:18
  • Yes, but I'm trying to make a minimum reproduction to troubleshoot. I don't know what `this.componentActive` does. If my version still gives you that error then look to the backend/endpoint for the problem. – Ben Racicot Jun 13 '19 at 13:21
  • componentActive is a boolean that gets changed to false when the onDestroy lifecycle hook gets called. The endpoint does get the data as expected. – BartKrul Jun 17 '19 at 14:16
  • A couple ideas I had over the weekend for you: If you remove the pipe and only subscribe do you get your data? Also I'm still skeptical of the server/endpoint. Do server logs give any details that may identity the 504? – Ben Racicot Jun 17 '19 at 15:16
0

Make sure that your service request to return promise. Like :

getData(): Promise<Array<string>> {
    return this.http.get("http://a-test-api.com/api/getdata").toPromise();
}
Rahul Tagore
  • 101
  • 9