Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error handling on request piping

Tags:

I wrote simple proxy on nodejs and it looks like

var request = require( 'request' ); app.all( '/proxy/*', function( req, res ){     req.pipe( request({         url: config.backendUrl + req.params[0],         qs: req.query,         method: req.method     })).pipe( res ); }); 

It works fine if remote host is available, but if remote host is unavailable the whole node server crashes with unhandled exception

stream.js:94                                                      throw er; // Unhandled stream error in pipe.                      ^                                               Error: connect ECONNREFUSED                                     at errnoException (net.js:901:11)                           at Object.afterConnect [as oncomplete] (net.js:892:19)  

How can I handle such errors?

like image 457
ioncreature Avatar asked Nov 25 '13 14:11

ioncreature


People also ask

What is the best way to implement error handling in pipeline?

Define the business logic, and depends on the outcome of the activity, enacts either Upon Success path or Upon Failure path Both are valid ways to incorporate error handling into the pipeline. However, upon pipeline execution, they may show different outcomes.

How to handle errors in a piped stream?

To handle errors in the above case of piped streams, we have to add an error handler on each of the streams like this: As a result, if any of the streams encounters an error, its corresponding error handler will be triggered and the process will not exit due to unhandled errors.

How do you handle errors with async pipe?

In order to handle errors properly, we are going to use *ngIf with async pipe. Even when using *ngFor, we need to wrap it around an *ngIf container. This is because *ngIf provides else statement, allowing us to provide a template if the operation fails or the request is still in progress.

How to handle errors in a pipe in Node JS?

In Node, a pipe does not forward error to the next pipe. To handle errors in the above case of piped streams, we have to add an error handler on each of the streams like this: As a result, if any of the streams encounters an error, its corresponding error handler will be triggered and the process will not exit due to unhandled errors.


2 Answers

Looking at the docs (https://github.com/mikeal/request) you should be able to do something along the following lines:

You can use the optional callback argument on request, for example:

app.all( '/proxy/*', function( req, res ){   req.pipe( request({       url: config.backendUrl + req.params[0],       qs: req.query,       method: req.method   }, function(error, response, body){     if (error.code === 'ECONNREFUSED'){       console.error('Refused connection');     } else {        throw error;      }   })).pipe( res ); }); 

Alternatively, you can catch an uncaught exception, with something like the following:

process.on('uncaughtException', function(err){   console.error('uncaughtException: ' + err.message);   console.error(err.stack);   process.exit(1);             // exit with error }); 
like image 103
Tom Grant Avatar answered Oct 20 '22 01:10

Tom Grant


If you catch the uncaught exception for ECONNREFUSED make sure to restart your process. I saw in testing that the socket becomes unstable if you ignore the exception and simply try to re-connect.

Here's a great overview: http://shapeshed.com/uncaught-exceptions-in-node/

I ended up using the "forever" tool to restart my node process, with the following code:

process.on('uncaughtException', function(err){ //Is this our connection refused exception?   if( err.message.indexOf("ECONNREFUSED") > -1 )   {     //Safer to shut down instead of ignoring     //See: http://shapeshed.com/uncaught-exceptions-in-node/     console.error("Waiting for CLI connection to come up. Restarting in 2 second...");     setTimeout(shutdownProcess, 2000);    }   else   {    //This is some other exception..     console.error('uncaughtException: ' + err.message);    console.error(err.stack);    shutdownProcess();   } });  //Desc: Restarts the process. Since forever is managing this process it's safe to shut down //      it will be restarted.  If we ignore exceptions it could lead to unstable behavior. //      Exit and let the forever utility restart everything function shutdownProcess() {   process.exit(1); //exit with error } 
like image 38
bschwagg Avatar answered Oct 20 '22 00:10

bschwagg