1

I have a script that capture the errors and send them to my server. But I'm worried that if I have a lot of users, and every user gets a couple errors, it may collapse my server.

This is my code:

window.onerror = function(msg, url, num) {
  try {
    var clientSideErrorInfo = {
      message: msg,
      url: url,
      num: num
    };

    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'http://domain/api/v1/browser/', true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(clientSideErrorInfo));

    console.log(clientSideErrorInfo)
  } catch (e) {
    console.log(e);
    // Don't allow for infinitely recursively unhandled errors
    return true;
  }
};

Is there a way to send a group of logs instead of sending them one by one?

Thanks

1
  • 2
    You can and should throttle it on the client side, but to protect your server from collapse, you need to look for a server side strategy, because a malicious client could abuse your api. If one client creates to many requests, then your server should send back a 429 so that the client on the one hand knows that it should throttle down the requests. But your server should then also reject all further requests, until it cools down again. Commented Jul 21, 2017 at 11:42

4 Answers 4

2

Instead of sending the error at the moment you get it, you could collect all errors into a global variable and you send them using an interval. This way you can limit how many errors you want to send at a same time and you could increase your interval as well.

 var errorSend = {};
errorSend.listErrors = [];
errorSend.maxErrors = 50;
errorSend.interval = 100;

window.onerror = function(msg, url, num) {

    var clientSideErrorInfo = {
      message: msg,
      url: url,
      num: num
    };

    listErrors.push(clientSideErrorInfo);
    console.log(clientSideErrorInfo)

};

function sendErrors() {
    if (errorSend.listErrors>errorSend.maxErrors) {
        console.log("Too many errors to send");
        return;
    }
    var errors = {list: errorSend.listErrors};
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'http://domain/api/v1/browser/', true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(errors));


}
setInterval(sendErrors,errorSend.interval);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I could use "window.onbeforeunload" to send the logs instead of interval or use both methods.
2

Something very simple,umm:

  var body =[];

    setInterval(function(){
      //Using a copy of the error queue
      let batch = body.slice();
      var xhr = new XMLHttpRequest();
        xhr.open("POST", 'http://domain/api/v1/browser/', true);
        xhr.setRequestHeader("Content-Type", "application/json");
        let myJson = JSON.stringify(body);
        xhr.send({
            data:{
                param: myJson
            }
       });
       //Updating the main queue to contain only unsent error messages
       body=body.slice(batch.length,body.length);
    },time_you_specify);

    window.onerror = function(msg, url, num) {
      try {
        var clientSideErrorInfo = {
          message: msg,
          url: url,
          num: num
        };

      body.push(clientSideErrorInfo);

        console.log(clientSideErrorInfo)
      } catch (e) {
        console.log(e);
        // Don't allow for infinitely recursively unhandled errors
        return true;
      }
    };

Comments

1

Is not problem for this job but if you have a lot of errors in you web app can be problem. First you will need to setup your javascript code to the perfect state. In that case you idea is good ( catch every possible error ) . Just put it in some table on server . Heres from mozilla dev site about param :

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        var message = [
            'Message: ' + msg,
            'URL: ' + url,
            'Line: ' + lineNo,
            'Column: ' + columnNo,
            'Error object: ' + JSON.stringify(error)
        ].join(' - ');

        alert(message);
    }

    return false;
};

Very important use (userAgent) detectBrowser data , you must know which device is used also which browser is used -just add data intro your function. In 90% your client error will happend only on specific platforms . For example on android chrome ver < 23 ...

Please don't use interval for this kind of tasks , just on error catch event send error log to the server just like you already did!

Comments

0

It is better to use message queueing infrastructure, if you are expecting millions of messages

some sample

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.