Search code examples
javascripterror-handlingcatch-block

Catch is not handling rejection of promise


so, my problem is the following. I'm returning a promise which resolves when there are no problems while storing some data, but if (1.) The directory where I want to to save the file doesn't exists or (2.) In that folder already exists a file with that name; the promise rejects an specific error.

Router.post('/save/:userid?/:name?/:type?/:payload?', ( request, response ) => {

    let promise = new Promise( async ( resolve, reject ) => {

        let params = { ...request.params, ...request.query, ...request.body };
        let path = `./GameContent/Data/${ params.userid }`;
        let fileStream = new FileStream();

        let exists = await fileStream.directoryExists( path );
        if ( exists ) {

            let fileDirectory = `${ path }/${ params.name }.json`;
            exists = await fileStream.directoryExists( fileDirectory );

            if ( !exists ) {

                let bytesWritten = await fileStream.writeFileAt ( fileDirectory, params.payload );
                let result = { name: params.name, bytes: bytesWritten, error: 0 };

                resolve( JSON.stringify( result ) );
            }
            else {

                let result = { error: 102 };
                reject( JSON.stringify( result ) );
            }
        }
        else {

            let result = { error: 101 };
            reject( JSON.stringify( result ) );
        }
    });
    response.send( promise );
});

So far so good, but, the problem is that the following code is not handling the rejection.

$.post('/api/save', levelJSON)
        .catch ( err =>  {
            //Do something...
        });

I'm currently receiving the error that I expected (error: 102). But, I haven't been able to handle the error.

The debbuger is throwing this: UnhandledPromiseRejectionWarning: {"error":102} UnhandledPromiseRejectionWarning: Unhandled promise rejection.


Solution

  • jQuery $.post has no .catch() method for error catching. You can try .fail() method instead like:

    $.post('/api/save', levelJSON)
        .done(function (response) {
            // success logic here        
        })
        .fail(function (jqXHR, exception) {
            // Error logic here
            var msg = '';
            if (jqXHR.status === 0) {
                msg = 'Not connect.\n Verify Network.';
            } else if (jqXHR.status == 404) {
                msg = 'Requested page not found. [404]';
            } else if (jqXHR.status == 500) {
                msg = 'Internal Server Error [500].';
            } else if (exception === 'parsererror') {
                msg = 'Requested JSON parse failed.';
            } else if (exception === 'timeout') {
                msg = 'Time out error.';
            } else if (exception === 'abort') {
                msg = 'Ajax request aborted.';
            } else {
                msg = 'Uncaught Error.\n' + jqXHR.responseText;
            }
            console.log(msg)
        });
    

    You can update the Router code to catch error like:

    Router.post('/save/:userid?/:name?/:type?/:payload?', (request, response, next) => {
    
      let promise = new Promise(async (resolve, reject) => {
        // Your current code here...
      });
    
      promise
        .then(function(result) {
          response.send(result);
        })
        .catch(next);
    });
    

    and the add an error handling middleware to your express app like:

    app.use(function(err,req,res,next) {
      console.log(err.stack);
      res.status(500).send({"Error" : err.stack});
    });