Dear all,
in my application i have implemented neverthrow to indicate, whether a result is Ok or an Err. This result is passed back to the controller, where it can be properly handled (i.e., show error messages). Checking for an error may look like this:
async getUserById(id: string) {
const result = await this.userService.getById(id);
// console.log(typeof result); // --> may be of type "Err"
// console.log(result.constructor.name); // --> may be "Err"
if (result.isErr()) {
throw result.error
}
return result;
}
As i do not want to have those checks (or try/catch) in my controller methods, i thought about handling this in an Interceptor and apply the latter to all routes globally.
However, when i created a minimal interceptor, i noticed, that the type information (i.e., the result from the controller method is a type Result<User, Error>) is lost. The information, however, is present in the controller.
My interceptor looks like this:
@Injectable()
export class ExceptionInterceptor<T> implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<T> {
return next.handle().pipe(
map((data) => {
console.log(typeof data); // --> returns "object"
console.log(data.constructor.name); // --> returns "Object"
// ...
}),
);
}
}
It seems that the type information (i.e., the type) is lost when it is passed into the pipe() method from the Observable. What i would actually like to have is:
@Injectable()
export class ExceptionInterceptor<T> implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<T> {
return next.handle().pipe(
map((data) => {
if (data instanceof Result) {
if(data.isErr() {
throw data.error;
}
// ...
}
}),
);
}
}
Am I missing something crucial here?
All the best and thanks for your help!