How to best handle http request errors

Posted on
  • I am making POST requests to a web server via SIM800. I have a req.on('error', function(e)) in place but I find that only catches one particular error (I cant remember the code right now)

    However in the SIM900 code if either the CIPSTART command fails or there is a CONNECT FAIL, even though the SIM900 code was throwing an exception and setting the socket to undefined - the http request function does not generate an error. I assume there is no mechanism to ripple those errors back through.

    So for now I have implemented my own callbacks from the SIM900 code to capture those errors so I can retry. But the question is, how do I ensure the existing http request is properly killed off so I dont leak memory from retries ? Or worse the request code ends up returning something (error or not) after I have already captured an error and begun a retry.

  • Thanks - That looks like an issue with the SIM900 code then. The idea is that the send and recv functions in the JS code return a non-string value to signify an error (usually -1).

    You've made your own tweaked module haven't you? I think in the CIPSTART case, literally just removing the line throw new Error('CIPSTART failed.') will fix it - as then the socket data gets set to undefined, and next time Espruino tries to read or send data, the error will get reported back and the socket will get closed with everything freed.

    You could also look at where the handler for CONNECT OK is and add your own connect fail handler:

              at.registerLine(sckt + ', CONNECT FAIL', function() {
                at.unregisterLine(sckt + ', CONNECT FAIL');
                socks[sckt] = undefined;
                return "";
              });
    
  • Yes I have already removed the exception throws but I thought that was not enough to get the error to come back through the network library - but maybe I should recheck that. I currently have my own callback in both the CIPSTART fail and CONNECT FAIL case - but then I dont know when the socket etc is freed.

  • Just looking at it now I see that the 'send' function is waiting for the socks entry to be set from 'Wait' to either 'true' or 'undefined', the latter will then trigger the -1 return in the case of the error. So in theory without the throw this should be working - I will check that again

  • I think it is not a problem with the SIM900 code. It is regarded, how AT commands get executed at the modem. I can reproduce this, when I run shortly after another two command, awaiting replies from the modem. e.g.: isOnline(); networkTasks() (my own code)
    If avoiding this so called "concurrent" - in JS-Terms better say, overlapping operations - it might be fixed. However the hardware cannot not deal with the commands in a concurrent mode. So each has to be send at a time and pseudo-synchronously should receive its result, before proceeding to the next one.

    req start
    =undefined
    error request
    Uncaught Error: CIPSTART failed.
     at line 1 col 68
    ...ew Error('CIPSTART failed.');at.registerLine(a+', CONNECT OK...
                                  ^
    in function "a" called from line 1 col 31
    c=undefined;var d;if(a&&(d=a(g))?(c=h,a=d):clearTimeout(­j),c...
                                  ^
    in function "c" called from line 1 col 331
    ...e&&(d[e](i),j=!0);j||c&&c(i);}if(a=a.­substr(f+h.length),a[0]...
    
  • Ahh - yes, maybe the driver should be more aware.

    If you do one command while waiting for the result of another it should throw an error, but you can definitely get into a position where you asked it to do something (like connect) and it's said OK so Espruino thinks it's not busy, and waits until CONNECT (or similar) is sent. Between OK and CONNECT it's possible you could do something else, and in that case it could fail.

  • I really think each programmer should know this. We're dealing on a very low level on that hardware. Everyone has to be careful how he deals with it.... So I would say, not for sure the module needs to handle it.

    I have to think about it.

    In my case I was just receiving the IP-Adress from the SIM900 on timeinterval with a special AT-command (not with the SIM900 code). At the time this command did not resond properly, and I started the request, it got mixed up and the request failed with above error. Now as solution I do one operation at a time.

    I prevent status requests on that hw, when I am aware I need to make a request. I personally gave the last one the higher priority.

  • Introducing a queue can help with that... but the queue entry has also to include what has to happen when the result becomes available. I have built a sequencer / gl0bal controller that supports such needs including inserting entries that 'cut into the line': sometimes the response of a currently going on request cycle needs to trigger something else than what's next in queue.

    (see this post and posts referenced in there.

  • Perhaps the new promise additions to the new 1.86 firmware would allow you to easily manage the queuing and next event via JavaScript?

  • I will try. I didn't know I could use promises on the espruino. great.

  • Another thing (maybe offtopic) After a certain time the requests also do not get through I get the error:

    Uncaught Error: No free sockets.
    at line 1 col 306
    ...ew Error('No free sockets.');return socks[a]='Wait',sockData...

    when is the netcallback.create to be called in SIM900?

  • Generally it's called when you make a client or server socket.

    If you're getting no free sockets it's either because connections aren't closing for some reason, or maybe the SIM900 module isn't catching the socket closed message for some reason and updating its internal list of used sockets.

  • I think, the AT-Module must lock AT commands until they responded properly. I overthought it at this level.

  • -deleted-

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to best handle http request errors

Posted by Avatar for jonreid @jonreid

Actions