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.

1 Answer 1

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);
  });
Sign up to request clarification or add additional context in comments.

5 Comments

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"
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
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.
How would you make the client work for Template functions? When I pass the object into the post, it does not work.
@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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.