Angular 13 HttpClient捕获404错误:订阅返回空对象问题求助
问题原因及解决方案
错误点1:Error对象序列化导致空输出
你在catchError里抛出的是new Error('Blah'),但Error实例的核心属性(如message)是不可枚举的,直接用JSON.stringify()序列化会得到空对象{},这就是订阅的error回调返回空内容的原因。
错误点2:未针对性处理404错误
当前代码没有判断错误的状态码,不管什么类型的HTTP错误都返回固定信息,不符合你“捕获特定404”的需求。
错误点3:map操作中的错误日志误导
你的map操作里写了Logger.error(Error : ${response.status}),但只有当HTTP请求返回2xx成功状态码时才会进入map,这里的日志会造成误解,建议改为信息类日志或直接删除。
修正后的服务代码
findOne(id: number): Observable<Intern | undefined> { return this.httpClient.get<any>( `${environment.apiRoot}intern/${id}`, { observe: 'response' } ).pipe( take(1), map((response: HttpResponse<any>) => { Logger.info(`请求成功,状态码:${response.status}`); const rawIntern: any = response.body; const intern: Intern = new Intern(); intern.id = rawIntern.id; intern.name = rawIntern.name; intern.firstname = rawIntern.firstName; intern.birthDate = new Date(rawIntern.birthDate); intern.address = rawIntern.address; intern.phoneNumber = rawIntern.phoneNumber; intern.email = rawIntern.email; return intern; }), // 将catchError放在map之后,确保仅处理请求错误 catchError((error) => { Logger.error('请求出错:', error); // 针对性捕获404错误 if (error.status === 404) { // 返回可序列化的错误信息,比如字符串或自定义对象 return throwError(() => '实习生记录不存在(404)'); } else { return throwError(() => '未知请求错误'); } }) ); }
修正后的组件订阅代码
现在抛出的是可序列化的内容,JSON.stringify能正常输出错误信息:
this.internService.findOne(this._id).subscribe({ next: (intern: Intern | undefined) => { this.intern = intern; }, error: (error) => { Logger.error(JSON.stringify(error)); // 如果用自定义错误对象,可直接处理UI逻辑 // if (error.includes('404')) { /* 显示404提示 */ } } });
简化版可选方案(去掉observe: 'response')
如果不需要获取完整的HTTP响应对象,可简化代码,直接处理响应体:
findOne(id: number): Observable<Intern | undefined> { return this.httpClient.get<any>(`${environment.apiRoot}intern/${id}`).pipe( take(1), map(rawIntern => { const intern: Intern = new Intern(); intern.id = rawIntern.id; intern.name = rawIntern.name; intern.firstname = rawIntern.firstName; intern.birthDate = new Date(rawIntern.birthDate); intern.address = rawIntern.address; intern.phoneNumber = rawIntern.phoneNumber; intern.email = rawIntern.email; return intern; }), catchError((error) => { return error.status === 404 ? throwError(() => '实习生记录不存在') : throwError(() => '请求失败'); }) ); }
内容的提问来源于stack exchange,提问作者Jean-Luc Aubert
相关产品推荐
相关产品推荐

