如何从API角度获取错误消息?

时间:2019-06-15 06:44:26

标签: angular

我正在使用Angular 6,并且我有一项服务,该服务尝试通过发出POST请求在后端数据库中创建记录。我在这样的服务中实现此请求:

... usual imports and other Angular boiler plate omitted for brevity ...

export class SitesService {

  constructor(private http: HttpClient) {}

  addSite(siteName){
    const url = environment.apiUrl + '/api/v1/spi/sites/';
    const body = { 'name': siteName };

    const header = new HttpHeaders({'Content-Type':  'application/json' });
    return this.http.post(url, body, { headers: header }).pipe(map ( res => <Site>res ));
  }

我在组件代码中使用了上述服务:

... usual imports and Angular boiler plate omitted for brevity ...

export class SitesComponent implements OnInit {

  ... local variable declaration omitted ...

  constructor(private service: SitesService) {
       ... more unrelated code omitted ...


  addSite(siteName) {
    this.showLoader = true;
    this.service.addSite(this.siteName).subscribe(
      data => this.postSuccess(data),
      error => this.postError(error)
    );
  }

  private postError(error) {
      console.log('ERROR IS');
      console.log(error);
      ... omitted ...
  }

当API响应BAD REQUEST 400时,我知道它会提供一条消息以及状态编号400。正如我在浏览器开发者控制台中看到的那样:

enter image description here

但是我所有的postError()方法所做的都是这样写入控制台:

ERROR IS
Bad Request

我希望能够输出name: This field is required.

这是一个屏幕截图,显示我得到的响应代码为400,而不是200。

enter image description here

更新

事实证明,我们团队中有人已经实施了拦截器。这是它的代码:(我添加了console.log's)。

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import {LoginService} from '../login/login.service'



@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private authenticationService: LoginService) {}
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
          console.log('ErrirInterceptor err is:');
          console.log(err);
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                this.authenticationService.logout();
            }
            const error = err.error.message || err.statusText;
            return throwError(error);
        }))
    }
}

当我访问麻烦的api时,console.log的输出:

ErrirInterceptor err is:
error:
name: Array(1)
0: "This field is required."
...

但是我仍然不明白如何将错误消息发送给我 SitesComponentSitesService类。

UPDATE II

事实证明,先前编写的拦截器无法处理Django Generic Views生成的错误响应,因此我通过更改此行来对其进行了更新...

            const error = err.error.message || err.statusText;

...对此:

            const error = err.error.message || err.error.name || err.statusText;

1 个答案:

答案 0 :(得分:1)

使用拦截器创建文件

import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/do';


@Injectable( {
    providedIn: 'root'
} )
export class YourInterceptor implements HttpInterceptor {
    constructor () { }

    intercept ( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> {

        return next.handle( request )
            .do( ( response: HttpEvent<any> ) => {
                if ( response instanceof HttpResponse ) {
                    for ( const key of response.headers.keys() ) {
                        console.log(key); // ***** The message should come out here ******
                    }
                }
            }, ( error: any ) => {
                if ( error instanceof HttpErrorResponse ) {
                    console.error( error );
                    console.error( error.status );
                }
            } );
    }
}

然后将其导入到应用程序的主模块中

import {
    YourInterceptor
} from './interceptors/.yourInterceptor';



    @NgModule( {
    declarations: [ . . . ],
    imports: [ . . . ],
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: YourInterceptor,
            multi: true
        }
    ],
    bootstrap: [ . . . ]
} )