简体   繁体   中英

Propagate rejected promise via a .catch()

I have some code which essentially looks like this:

export function firstFunction(req: express.Request, res: express.Response, next: express.NextFunction): void {
  secondFunction(id)
  .then((userId: UserId) => {
    res.status(200).send(UserId);
  })
  .catch((err) => {
    if (err instanceof NoResultError) {
      res.status(404).send(err);
    } else {
      next(err);
    }
  });
}


export function secondFunction(id: string): Promise<UserId> {
  return new Promise<UserId>((resolve, reject) => {
    thirdFunction(id)
    .then((data: TableInfo) => {
      if (Object.keys(data).length !== 3) {
        reject(new Error('data in database is not mapped properly'));
      }
      resolve(data);
    })
    .catch((err) => {
      // WANT TO PROPAGATE ERROR UP TO THE GETDETAILS FUNCTION WHICH CALLS THIS
    });
  });
}

export function thirdFunction(id: string): Promise<TableInfo> {
  return new Promise<TableInfo>((resolve, reject) => {
    let query = `
        //query goes here
    `;
    db.executeQuery(query, [id])
    .then((data: TableInfo) => {
      if (Object.keys(data).length < 1) {
        reject(new NoResultError('some message here'));
      }
      resolve(data);
    });
  });
}

My goal is to have the lowest level of the three functions (thirdFunction) determine if the data from the db-query finds no data and then reject that promise with an error. Then the secondFunction should ideally catch this error and propagate it up to firstFunction so that firstFunction can handle that error properly. I have tried doing a throw err a return err and a return Promise.reject(err) all of which lead to an unhandled promise rejection. What is my (probably fundamental) misunderstanding of how this should work?

the secondFunction should ideally catch this error and propagate it up

No, propagation is the default. Ideally you should not need to catch it at all, and it will propagate up automatically.

I have tried things that all lead to an unhandled promise rejection. What is my (probably fundamental) misunderstanding?

You're using the Promise constructor antipattern ! With it, you would need to call reject(err) in the catch handler to make it work. Or really .then(resolve, reject); . But that's absolutely not how this should be done.

Instead, drop the new Promise wrapper and just return the result of chaining then handlers:

export function secondFunction(id: string): Promise<UserId> {
  return thirdFunction(id)
  .then((data: TableInfo) => {
    if (Object.keys(data).length !== 3) {
      throw new Error('data in database is not mapped properly');
    }
    return getUserId(data);
  });
}

export function thirdFunction(id: string): Promise<TableInfo> {
  let query = `/* query goes here */`;
  return db.executeQuery(query, [id])
  .then((data: TableInfo) => {
    if (Object.keys(data).length < 1) {
      throw new NoResultError('some message here');
    }
    return data;
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM