22

I am using a REST service to generate a CSV file that I want to prompt the user to download. An example of the service is below:

https://localhost:8444/websvc/exportCSV?viewId=93282392

To prompt the user to download the file, I use this code:

window.location.href = exportUrl, where exportUrl would be a URL like the one above.

This works great if there are no errors on the server when executing the service. The file download prompt appears, the page doesn't refresh, and all is well.

However, if there is an error, I'm getting a nasty HTTP Status 500 page, which is no good for user experience. What I'd like to do is catch any error on the resulting page, and throw up a more friendly error without leaving the current page. I tried:

try {
    window.location.href = exportUrl;
}
catch (e) {
    alert(e);
}

But that doesn't seem to change the behavior at all. Does anyone have any ideas on how to handle this?

Thanks very much.

Matt
  • 23,363
  • 39
  • 111
  • 152

1 Answers1

11

Catching an error like that will only catch a JavaScript error. That's not what you're experiencing here. Your server is returning a status code of 500. You need to make sure that everything is good BEFORE you send your users there.

To do that you could effectively 'ping' the URL with Ajax to ensure that it won't return a 500 error.

Something like the following:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
    if(xhr.readyState == 4 && xhr.status == 200) {
        window.location.href = exportUrl;
    }
}

xhr.open('head',exportUrl);
xhr.send(null);

This would do a HEAD request to the URL to ensure that there are no nasty server errors waiting.

Of course, if in the process of actually GENERATING the CSV your server throws an error - it would still return a 500.

A more robust way would be to get the data via Ajax, build a data URL via base64encode and then set window.location.href to that data URL.

By doing that, you could also ensure that the Ajax didn't return a 500 and you got the data you were expecting in the response.

Hope this helps!

daniel0mullins
  • 1,937
  • 5
  • 21
  • 45
  • 2
    Thanks very much for that. While I was waiting on an answer, I decided to do something similar. I'm now using $.get() to hit the url *first*, and in the done() function I put the window.location.href code. In the fail() function, I throw up a friendly error saying the file generation was unsuccessful. That's working, but it means two full hits to the server, which I'm not a big fan of. It's important to note that the error is definitely happening during CSV *generation*, so I'm interested in your second, "more robust" idea. Can you expand on how to build a data URL using `base64encode`? Thanks – Matt Sep 19 '13 at 20:31
  • @MattPowell did you find a solution for this? (with just one hit to the server) – IceWhisper Aug 02 '17 at 07:41
  • Hi @IceWhisper - no, I'm sorry, I never did. Two server hits is accetable in my case, but I'd run down the `base64encode` data URL if I needed a single server hit. – Matt Aug 02 '17 at 12:26