我有一些基本上看起来像这样的代码:
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);
});
});
}
我的目标是让三个函数中的最低级别(thirdFunction)确定来自db-query的数据是否找不到数据,然后拒绝该带有错误的promise。然后第二个函数应理想地捕获此错误并将其传播到firstFunction,以便firstFunction可以正确处理该错误。我尝试过throw err
一个return err
和一个return Promise.reject(err)
所有这些导致未经处理的承诺拒绝。什么是我(可能是根本的)对这应该如何运作的误解?
答案 0 :(得分:3)
理想情况下,secondFunction应该捕获此错误并将其传播
不,传播是默认值。理想情况下,您根本不需要捕获它,它会自动传播。
我尝试了所有导致未经处理的承诺拒绝的事情。我的(可能是根本的)误解是什么?
您正在使用Promise
constructor antipattern!有了它,您需要在reject(err)
处理程序中调用catch
才能使其正常工作。或者真的.then(resolve, reject);
。但这绝对不是应该如何做到的。
相反,删除new Promise
包装器,只返回链接then
处理程序的结果:
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;
});
}