如何处理 Observable 中的多个 catchError?
How to handle multiple catchError in Observable?
第一次使用 NestJs 和 Observables。我很熟悉如何使用 Promises 解决这个问题,但我想扩展我对 Observables 的了解。
下面是一个“注册”功能,需要做几件事。首先,它创建租户,然后根据租户的结果创建用户。
如果租户或用户已经存在,则会引发违反唯一约束的错误。如果发生错误,我想做的是从 observable 中解救出来,并将 return 错误发送给控制器。在捕捉到第一个错误时最终会发生什么,它将在第二个“catchError”
中再次被捕捉到
我已经在下面的第二个“catchError”中处理了这个问题(通过查找 BadRequestException),但这感觉不对。我的问题是是否有更好的方法来处理这个问题?
提前致谢!
signup(signUpDto: SignupRequestDto, tenantDto: TenantDto): Observable<User> {
const createTenant$ = from(
this.createTenant(tenantDto.name, tenantDto.key),
);
const user = createTenant$.pipe(
catchError((error, caught) => {
const err = error as PrismaClientKnownRequestError;
this._logger.error({ err, caught }, 'tenant err');
// Unique constraint violation
if (err.code === 'P2002') {
throw new BadRequestException(
'Tenant already exists',
tenantDto.name,
);
} else {
throw new InternalServerErrorException('Error creating user');
}
}),
switchMap((tenant) => {
return from(this.createUser(signUpDto, tenant.id));
}),
catchError((error, caught) => {
// If this is error is already handled by the catchError above
if (error instanceof BadRequestException) {
throw error;
} else {
const err = error as PrismaClientKnownRequestError;
this._logger.error({ err, caught }, 'user err');
// Unique constraint violation
if (err.code === 'P2002') {
throw new BadRequestException('Email already exists');
} else {
throw new InternalServerErrorException('Error creating user');
}
}
}),
);
return user;
}
您可以使用单个 catchError
来实现它,但问题是识别 来源 。为此,我使用了一个私有变量来识别来源。
private currentEvent: string = 'createTenant'; //default value createTeanant
private currentEvent: string = 'createTenant';
signup(signUpDto: SignupRequestDto, tenantDto: TenantDto): Observable<User> {
const createTenant$ = from(
this.createTenant(tenantDto.name, tenantDto.key)
);
return user = createTenant$.pipe(
switchMap((tenant) => {
currentEvent = 'createUser';//Assigning new event name
return from(this.createUser(signUpDto, tenant.id));
}),
catchError((error, caught) => {
const err = error as PrismaClientKnownRequestError;
this._logger.error({ err, caught }, this.currentEvent + ' err');
// Unique constraint violation
if (err.code === 'P2002' && this.currentEvent === 'createTenant') {
throw new BadRequestException(
'Tenant already exists',
tenantDto.name
);
} else if (err.code === 'P2002' && this.currentEvent === 'createUser') {
throw new BadRequestException('Email already exists');
} else {
throw new InternalServerErrorException('Error creating user');
}
})
);
}
第一次使用 NestJs 和 Observables。我很熟悉如何使用 Promises 解决这个问题,但我想扩展我对 Observables 的了解。
下面是一个“注册”功能,需要做几件事。首先,它创建租户,然后根据租户的结果创建用户。
如果租户或用户已经存在,则会引发违反唯一约束的错误。如果发生错误,我想做的是从 observable 中解救出来,并将 return 错误发送给控制器。在捕捉到第一个错误时最终会发生什么,它将在第二个“catchError”
中再次被捕捉到我已经在下面的第二个“catchError”中处理了这个问题(通过查找 BadRequestException),但这感觉不对。我的问题是是否有更好的方法来处理这个问题?
提前致谢!
signup(signUpDto: SignupRequestDto, tenantDto: TenantDto): Observable<User> {
const createTenant$ = from(
this.createTenant(tenantDto.name, tenantDto.key),
);
const user = createTenant$.pipe(
catchError((error, caught) => {
const err = error as PrismaClientKnownRequestError;
this._logger.error({ err, caught }, 'tenant err');
// Unique constraint violation
if (err.code === 'P2002') {
throw new BadRequestException(
'Tenant already exists',
tenantDto.name,
);
} else {
throw new InternalServerErrorException('Error creating user');
}
}),
switchMap((tenant) => {
return from(this.createUser(signUpDto, tenant.id));
}),
catchError((error, caught) => {
// If this is error is already handled by the catchError above
if (error instanceof BadRequestException) {
throw error;
} else {
const err = error as PrismaClientKnownRequestError;
this._logger.error({ err, caught }, 'user err');
// Unique constraint violation
if (err.code === 'P2002') {
throw new BadRequestException('Email already exists');
} else {
throw new InternalServerErrorException('Error creating user');
}
}
}),
);
return user;
}
您可以使用单个 catchError
来实现它,但问题是识别 来源 。为此,我使用了一个私有变量来识别来源。
private currentEvent: string = 'createTenant'; //default value createTeanant
private currentEvent: string = 'createTenant';
signup(signUpDto: SignupRequestDto, tenantDto: TenantDto): Observable<User> {
const createTenant$ = from(
this.createTenant(tenantDto.name, tenantDto.key)
);
return user = createTenant$.pipe(
switchMap((tenant) => {
currentEvent = 'createUser';//Assigning new event name
return from(this.createUser(signUpDto, tenant.id));
}),
catchError((error, caught) => {
const err = error as PrismaClientKnownRequestError;
this._logger.error({ err, caught }, this.currentEvent + ' err');
// Unique constraint violation
if (err.code === 'P2002' && this.currentEvent === 'createTenant') {
throw new BadRequestException(
'Tenant already exists',
tenantDto.name
);
} else if (err.code === 'P2002' && this.currentEvent === 'createUser') {
throw new BadRequestException('Email already exists');
} else {
throw new InternalServerErrorException('Error creating user');
}
})
);
}