0

Javascript in a webbrowser.

There is an async event handler. Inside this event handler a try/catch is used. Inside the try block an asynchoronous functions is called synchronously with await.

Inside the catch block the caught data should be processed. But instead of the error, it catches a rejected Promise with PromiseState: 'fullfilled' and the error it was rejected with as PromiseResult.

Code:

try {
    $(document).ready( async function handleEvent( event ) {
        try {
            //async function called synchronously
            await doSomethingAsync( event );
        } catch( xcp ) {
            //xcp is of type Promise
            //console output shows that it is a Promise with PromiseState: 'fullfilled'
            //and the Error as `PromiseResult`
            console.error( xcp );
        }
    });
} catch( xcp ) {
    console.error( xcp );
}

async function processAjaxError ( jqXHR, textStatus, errorThrown ) {
    let error = new Error ( "textStatus: "+textStatus+", errorThrown: "+errorThrown );
    return error;
}

async function doSomethingAsync( event ) {
    //using a Promise as return type
    return new Promise( function( resolve, reject ) {
        let ServerCall = {
            url: "example.com",
            type: "POST",
            data: {},
            dataType: 'json',
            success: function( data, textStatus, jqXHR ) {
                //success -> let the promise resolve
                resolve( data, textStatus, jqXHR );
            },
            error: function( jqXHR, textStatus, errorThrown ) {
                //failure -> let the promise reject
                let error = processAjaxError( ...arguments );
                reject( error );
            },
        }
        $.ajax( ServerCall );
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>

Why am I catching the rejected Promise instead of the Error the Promise was rejected with?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Creech
  • 258
  • 2
  • 12
  • 1
    Can you post your `doSomethingAsync`? I would strongly suggest investigating your side note 1. It is atypical to need to `catch` anything other than an Error, and even more so when using `await` to have to catch a Promise that keeps its Error in its non-error resolution value. Your code reads more like you would see `return Promise.resolve(new Error())` somewhere in your `doSomethingAsync`. – Jeff Bowman Mar 20 '23 at 16:49
  • try { ... } catch(error) {...} can't catch rejected promises except await them. Read this very nice article: https://dmitripavlutin.com/return-await-promise-javascript/ – ΑΓΡΙΑ ΠΕΣΤΡΟΦΑ Mar 20 '23 at 16:55
  • Thanks for your comments. I added the condensed code of `doSomethingAsync` to provide more context. It returns a `Promise`, it uses jQuery `ajax` and resolves or rejects the promise depending on if the `success` or the `error` handler of jQuery `ajax` was called. – Creech Mar 20 '23 at 17:27
  • 1
    "*there is a check if a `Promise` was caught*" - that does not make sense. One does not throw promises, one throws errors. – Bergi Mar 20 '23 at 17:45
  • 2
    Btw, [never pass an `async function` as the executor to `new Promise`](https://stackoverflow.com/q/43036229/1048572), and [don't pass callbacks to `$.ajax` but use the returned promise](https://stackoverflow.com/a/31327725/1048572)! – Bergi Mar 20 '23 at 17:47
  • Since the problem seems to be what I return from the async function, I changed subject and content of the question. – Creech Mar 20 '23 at 17:50
  • 1
    `reject( error );` will not reject the promise with a fulfilled promise. Please show us the rest of the code. Do you use `throw` or call `reject()` anywhere else? – Bergi Mar 20 '23 at 17:57
  • I added a code example for a complete html page, which reproduces the problem. My legacy code is magnitudes more spaghetti. But this is a condensed working example. – Creech Mar 20 '23 at 18:49
  • 2
    The problem - now that you moved `let error = new Error( "Ajax call failed" );` into `let error = processAjaxError( ...arguments );` is that `processAjaxError` is an `async` function which always returns a promise, which is inappropriate here. Remove the "`async`" and it'll throw the error as expected. – Bergi Mar 20 '23 at 19:46
  • That's it! Thanks a bunch! Do you want to answer the question? – Creech Mar 20 '23 at 19:57

0 Answers0