处理订阅调用 Angular 服务错误的正确方法

Proper way to deal with errors from subscribe call to Angular service

我是 Angular 新手,所以如果您看到任何明显的错误,请原谅。请随时为我指明正确的方向:)

我有一个调用控制器方法的 Angular 服务。它以前是这样调用的,它 return 编辑了一个对象,其中包含用于在浏览器中显示图像的数据

      return (this.http.post(`/api/vehicles/${vehicleId}/photos`, formData)
         .map(res => res); 

我被要求在上传图片时实现一个进度条,所以我在 http 调用中添加了 reportProgress 选项。我的服务现在有一个名为 uploadProgress 的 属性,我可以将其绑定到我的进度条并显示上传进度。

@Injectable()
export class PhotoService {

   uploadProgress: any;

...
   upload(vehicleId, photo) {

      let formData = new FormData();
      formData.append('file', photo);

      const uploadReq = new HttpRequest('POST', `/api/vehicles/${vehicleId}/photos`, formData, {
         reportProgress: true
      });

      return (this.http.request(uploadReq)
         .map((event) => {
            if (event.type === HttpEventType.UploadProgress) {
               this.uploadProgress = this.createProgress(event);
            } else if (event.type === HttpEventType.Response) {
               return event.body;
            }
         }));

   }

   private createProgress(event) {
      return {
         total: event.total,
         percentage: Math.round(event.loaded / event.total * 100)
      };
   }

我表单上的方法现在看起来像这样

   uploadPhoto() {
      var nElem: HTMLInputElement = this.fileInput.nativeElement;

      var file = nElem.files[0];
      nElem.value = '';

      this.photoSvc.upload(this.vehicleId, file)
         .subscribe(photo => {
            this.progress = this.photoSvc.uploadProgress;
            console.log('this.progress: ', this.progress);
            if (photo !== undefined) {
               console.log('Photo result:', photo);
               this.photos.push(photo);
            }
         },
            err => {
               this.toasty.error({
                  title: 'Error',
                  msg: err.text(),
                  theme: 'bootstrap',
                  showClose: true,
                  timeout: 5000
               });
         },
         () => { this.progress = null; });
   }

订阅块被触发了很多次,我用它来更新绑定到进度条的 "this.progress" 变量。它有效,我不确定这是否是正确的方法,但它有效。如果方法不对,请随时详细说明。

我现在无法弄清楚的问题是,如果执行控制器中的边缘情况(文件大小、文件类型、空文件等),它们 return BadRequest 错误如下面的示例,但我在订阅上的错误块没有捕捉到它们,所以吐司消息没有显示。相反,它转到我的全局错误处理程序。我想在此上传中显示更有意义的消息,而不是系统现在发出的通用 toast 消息。

if (file == null) { return BadRequest("Null file"); }
if (file.Length == 0) { return BadRequest("Empty file"); }

感谢您对此处发生的事情提供任何帮助。提前致谢!

好的,所以把这个归咎于复制和粘贴。当我的 sentry.io 代码发布错误 "err.text is not a function" 时,我意识到我的错误块不正确。我用了

            err => {
               this.toasty.error({
                  title: 'Error',
                  msg: err.text(),
                  theme: 'bootstrap',
                  showClose: true,
                  timeout: 5000
               });
         }

而不是

            err => {
               this.toasty.error({
                  title: 'Error',
                  msg: err.error,
                  theme: 'bootstrap',
                  showClose: true,
                  timeout: 5000
               });
         }

修复后,代码运行良好。不好意思,来晚了...