Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper error pattern for async functions using Promises in TypeScript

I want to make a typed async function with proper error handling.

I can define one like this:

export async function doSomething(userId:string) : Promise<ISomething | void> {

    let somthing: ISomething = {};

    try {
        something.user = await UserDocument.findById(userId);
        something.pet = await PetDocument.findOne({ownerId:userId});
        return Promise.resolve(something);
    } catch (err){
        console.log("I would do some stuff here but I also want to have the caller get the error.");
        return Promise.reject(err);
    }
}

...which seems to work, but (for reasons that are clear), if I try to assign the result to an ISomething object, I get the error Type 'void | ISomething' is not assignable to type 'ISomething'.

let iSomething:ISomething;
iSomething = await doSomething('12'); //this give me the error

I get why that is. My question is, what pattern should I use for error handling in a case like this? Note that if the return type is Promise<IProfile> instead then I get an error for the return Promise.reject(err); line (which would return Profile<void>).

In place of the line return Promise.reject(err); I can use throw err;, but there may be times where I'd want to use the Promise.reject pattern (like if I want to do some more things before I return).

I have a feeling that I'm missing something with promises / async, but I can't find typed examples that follow this pattern.

...note that if I use the full Promise pattern it works fine:

doSomething('12')
  .then( (something) => {//do stuff})
  .catch( (err) => {//handle error});

Should I just be using throw and forget about Promise.reject? If I use throw, will the .catch() be triggered appropriately?

like image 825
WillyC Avatar asked Jan 25 '17 22:01

WillyC


People also ask

How do you handle promises in asynchronous function?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.

Which is the best standard approach on error handling for async function?

Error handlingA try/catch block can be used to handle asynchronous errors in an async function. Alluding to the fact that an async function always return a Promise, one can opt to use a . catch() in place of a whole try/catch block.

How do you catch error in async function?

The await keyword before a promise makes JavaScript wait until that promise settles, and then: If it's an error, an exception is generated — same as if throw error were called at that very place. Otherwise, it returns the result.

How do you throw an error inside a promise?

Here's an example: new Promise((resolve, reject) => { resolve("ok"); }). then((result) => { throw new Error("Whoops!"); // rejects the promise }). catch(alert); // Error: Whoops!


1 Answers

Not returning a promise in the first place is how I usually implement the async await pattern:

export async function doSomething(userId:string) : Promise<ISomething>{

    let something: ISomething = {};

    try {
        something.user = await UserDocument.findById(userId);
        something.pet = await PetDocument.findOne({ownerId:userId});
        return something;
    } catch (err){
        console.log("I would do some stuff here but I also want to have the caller get the error.");
        throw(err);
    }
}

so if you don't have to do intermediate cleanup you could strip it down to:

export async function doSomething(userId:string) : Promise<ISomething>{    
    let something: ISomething = {};
    something.user = await UserDocument.findById(userId);
    something.pet = await PetDocument.findOne({ownerId:userId});
    return something;
}

and have

  • the subsequent awaited function catch the exception or

  • the calling function handle the rejected promise

like image 56
Arjan Avatar answered Oct 02 '22 12:10

Arjan