23

Below is an Asp.net Core WebAPI which returns bad request with Error details as to its param when let's say duplicate a user is trying to register.

public async Task<IActionResult> Register([FromBody] RegisterModel registerModel)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser
            {
                //TODO: Use Automapper instead of manual binding  

                UserName = registerModel.Username,
                FirstName = registerModel.FirstName,
                LastName = registerModel.LastName,
                Email = registerModel.Email
            };
            var identityResult = await this.userManager.CreateAsync(user, registerModel.Password);
            if (identityResult.Succeeded)
            {
                await signInManager.SignInAsync(user, isPersistent: false);
                return Ok(GetToken(user));
            }
            else
            {
                Console.WriteLine("Errors are : "+ identityResult.Errors);
                return BadRequest(identityResult.Errors);
            }
        }
        return BadRequest(ModelState);

The response is being handled at the Angular side as follows:

user.service.ts

register(user: User) {
   // let headers = new Headers({ 'Content-Type': 'application/json' });
   //var reqHeader = new HttpHeaders({ 'Content-Type': 'application/json'});
   const reqHeader = new HttpHeaders().set('Content-Type', 'application/json')
                            .set('Accept', 'application/json');
//return this.http.post(this.rootUrl + '/api/account/register', body,{headers : reqHeader});

    return this.http.post(this.apiUrl+ '/api/account/register', user,{headers : reqHeader});
}

above method being called out in:

register.component.ts

this.userService.register(this.registerForm.value)
        .pipe(map((res: Response) => res.json()))
        .subscribe(
            data => {
                this.alertService.success('Registration successful', true);
                this.router.navigate(['/login']);
            },
            (error:HttpErrorResponse) => {
                // let validationErrorDictionary = JSON.parse(error.text());
                // for (var fieldName in validationErrorDictionary) {
                //     if (validationErrorDictionary.hasOwnProperty(fieldName)) {
                //         this.errors.push(validationErrorDictionary[fieldName]);
                //     }
                // }
                // this.alertService.errorMsg(this.errors);
                console.log(error.error);
            });

When I tried to do Postman I get perfect result as below :

Postman Result: Screenshot 1

But the same result despite trying multiple code snippet doesn't work out and all it logs 'Bad result' as a response.

Angular Result: Screenshot 2

I did notice though the response lies in the network tab.. just short of an idea to process it.

Error Description: Screenshot 3

What's missing here? your response will be much appreciated !

Chandresh Khambhayata
  • 1,748
  • 2
  • 31
  • 60
Jason
  • 325
  • 2
  • 4
  • 12

5 Answers5

14

I was also facing the same problem in angular 7. However I fixed this today using below code :

In service :

registerUser(userdata): Observable<any> {
    return this.httpClient.post('url', userdata).pipe(catchError(this.handleError));
}

handleError(error: HttpErrorResponse) {
    return throwError(error);
}

In register.component.ts :

postData() {
    this.auth.registerUser(userdata).subscribe(
        (resp) => {
            console.log(resp);
        },
        (error) => {
            console.log(error.error);
        }
    );
}
kittu
  • 6,662
  • 21
  • 91
  • 185
sanjana tyagi
  • 141
  • 1
  • 3
2

Pls check. Maybe you implemented some global error handler or http request interceptor where you modify your error on the fly. Something like:

export class GlobalHttpInterceptor implements HttpInterceptor {...}

Or:

export class GlobalErrorHandler implements ErrorHandler {...}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Alex
  • 21
  • 2
  • Thank you, this was driving me crazy! The ErrorHandler was commented out while testing, but didn't realise there was also an Interceptor! Cheers – Caio Campos Aug 04 '23 at 00:33
1

Dotnet Core 400 Identity error response is an array of {code,description}. So to handle it in typescript, first define an interface(not required actually,but for strict type checking.

interface ClientError {
    code: string;
    description: string;
}

Then in the part where you handle error, do following,

(error:HttpErrorResponse) => { 
   if(error.status===400){            
      const errors: Array<ClientError> = error.error;
      errors.forEach(clientError => {
         console.log(clientError.code);
      });
   }
}

Update: This is specific to Identity Framework. (Login and Registration). In other areas, Error Handling will need a manual work to align with this pattern.

Code Name Jack
  • 2,856
  • 24
  • 40
0

You are getting 400 Http-status code from your API in angular app AND in postman as well:enter image description here

BTW: 400 status is API expected behavior. It failed to create user and sends error description along with appropriate HTTP-status (400).If you want to handle this API error, the best choice would be something like (referred angular HttpErrorResponse type):

this.userService.register(this.registerForm.value)
        .pipe(map((res: Response) => res.json()))
        .subscribe(
            data => {
                this.alertService.success('Registration successful', true);
                this.router.navigate(['/login']);
            },
            (error:HttpErrorResponse) => {
                let errorPayload = JSON.parse(error.message);
                //ToDo: apply your handling logic e.g.:
                //console.log(errorPayload[0].description
                console.log(error.error);
            });
n.prokhorov
  • 930
  • 7
  • 13
  • 1
    Refereed it too.. No Qualms with status code I am interested in error description it rendered at Postman. The problem, in the name of error I only see just a text "Bad result" at client. Nothing more ! – Jason Oct 29 '18 at 13:51
  • Couldn't the client have a Proxy which intercepts the error responses? – aledpardo Oct 29 '18 at 19:10
  • @Jason let errorPayload = JSON.parse(error.message) what is value of this in debugger? And what is state of (error:HttpErrorResponse) =>... argument object? Please provide a dump of this objects – n.prokhorov Oct 30 '18 at 08:30
  • @n.piskunov errorPayload = JSON.parse(error.message) results in 'Undefined'. and same happens with (errr:HttpErrorRrsponse...). some more screenshots are mentioned at https://github.com/angular/angular/issues/26817. However I noticed Expected outcome with **Http** and not with **HttpClient** (why so ?). Will post soon more details. – Jason Nov 01 '18 at 07:30
-2

I got same error

message: "Http failure response for https://localhost:44397/api/AddEmployee: 400 OK" name: "HttpErrorResponse" ok: false status: 400 statusText: "OK" url: "https://localhost:44397/api/AddEmployee"

just because of I forgot to add

formData: Employee = new Employee();

now it will be running fine with my .net core webapi Click here for code

coolbuddy
  • 11
  • 1