1

I use the following function to Post a object of a given class.

public Post<T>(object: T, url: string, httpOptions: {}): Observable<T> {
return this.httpClient.post<T>(`${environment.apiEndpoint}` + url, object, httpOptions)
  .pipe(
    catchError(this.handleError)
  );

}

This function is called in all the service that wants to post something. Like this.

public addEquipment(equipment: Equipment): Observable<Equipment> {
    return this.shared.Post<Equipment>(equipment, this.url, this.header);
}

addEquipment is then executed within the component that uses that service. Like this.

this.equipmentService.addEquipment(result)
    .subscribe((data: any) => { this.alertService.success(data) }, (error: any) => this.alertService.error(error));

The problem is when the API returns a error (that I can see includes a error message, in the network tab) it tells me that there is no body in the response. The API returns a HttpResult where the error message is added to the response field.

return new HttpResult { StatusCode = HttpStatusCode.Conflict, Response = "Error message"}

I use the following function to handle the errors.

private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
  // A client-side or network error occurred. Handle it accordingly.
  console.error('An error occurred:', error.error.message);
}
else {
  console.log(error);
  console.error(
    `Backend returned code ${error.status}, ` +
    `body was: ${error.error}`);
}
console.log(error);
return throwError(
  error.error)
};

It is Angular 6 and a ServiceStack API. All suggestions would be appreciated.

Atle Kristiansen
  • 707
  • 7
  • 28

1 Answers1

0

FYI it's preferable to return structured error responses in ServiceStack which you can do with:

HttpError.Conflict("Error message");

Which will let you catch it when using ServiceStack's TypeScript ServiceClient with:

try {
    var response = await client.post(request);
} catch (e) {
    console.log(e.responseStatus.message);
}

But from this answer for handling errors with Angular HTTP Client it suggests the error body should be accessible with:

this.httpClient
  .get("data-url")
  .catch((err: HttpErrorResponse) => {
    // simple logging, but you can do a lot more, see below
    console.error('An error occurred:', err.error);
  });
mythz
  • 141,670
  • 29
  • 246
  • 390
  • I see, I will take a look at the ServiceClient. However, the solution you gave, isn't that pretty much what I do? I just use a function instead? I get the HttpErrorResponse, it just doesn't have the response within it. In my specific case I get "409 Conflict" and not "Equipment already exists" – Atle Kristiansen Mar 16 '19 at 18:45
  • 409 Conflict sounds like it's coming from the Status Description not the response body. Can't speak to the error you're seeing but from everything I see `HttpErrorResponse.error` should [contain the body parsed as JSON or the body as text](https://stackoverflow.com/a/52085631/85785) – mythz Mar 16 '19 at 18:51
  • Yes, when I return HttpResult { StatusCode = HttpStatusCode.Accepted, Response="Added"} I get the response, but when I try to do the same for 409, I only get conflict, which for me does not make any sense.. looking at you guys Client now, and I think that I will start to use that instead. – Atle Kristiansen Mar 16 '19 at 18:58
  • How would you make the client work for Template functions? When I pass the object into the post, it does not work. – Atle Kristiansen Mar 16 '19 at 20:56
  • @AtleKristiansen I've no idea on what you're referring to, please post a new question with full details, where the issue is, including raw HTTP Request/Response headers. – mythz Mar 16 '19 at 20:58