DP3
DP3

Reputation: 128

Http response error.status received as 0 but not actual status

I am trying to handle error in my Angular 4 code when a service call is made. My requirement is to make perform some actions based on the error code like 403, 200 or whatever.

I am subscribing to Observable to get result of the service call. But every time I try to read the error code, I only see '0' in the error response.

getStatus():Observable<any>{
    let options = new RequestOptions({ headers: this.Headers });
    return this.http.get(this.Url,options)
      .map((res) => res.json())
      .catch((err:Response) => {return Observable.throw(err.json())})
  }

After this call, when I try to catch the error returned from the service, I only get '0' as the status code and not the actual one. But in browser console I see the actual status.

this.service.getStatus()
      .subscribe((status => {
        this.status = status.Status;
        this.toggleflag = (this.status === 'Yes' ? true : false);
      }
    ))
    .catch(error=> this.redirectToLoginPage(error));

Now in the redirect function, when I try to read the status code, I always get 0 not the actual status due to which the call failed.

private redirectToLoginPage(error) {

    if(error.message == 403){
      localStorage.clear();

      this.router.navigateByUrl('https://' + window.location.hostname);
// the code continues

I have been struggling with this for a long time, any help would be highly appreciated. Thanks in advance.

This is the caught response

Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers, …}
headers
:
Headers {_headers: Map(0), _normalizedNames: Map(0)}
ok
:
false
status
:
0
statusText
:
""
type
:
3
url
:
null

Upvotes: 3

Views: 3899

Answers (4)

Ciro Corvino
Ciro Corvino

Reputation: 2128

I got this same issue working on a spa project based on Angular and Asp.Net Core.

This issue depends from the missing of CORS headers in the http response that client receives from server. This response violates the browser CORS policy and most likely depends from not handled run time errors in the server.

Even catching all errors and putting into returning response some info and http status, Angular, when occur CORS constraints violations, doesn't allow to have access to any info of the response, not even the http status, and so it produces the "empty" response:

Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers, …} headers : Headers {_headers: Map(0), _normalizedNames: Map(0)} ok : false status : 0 statusText : "" type : 3 url : null..

I solved this issue putting CORS headers into the response returned by the ASp.Net Core api server to the client in this way:

   app.UseExceptionHandler(appError => {
                appError.Run(async context => {

                    var _config = ServiceProviderFactory.ServiceProvider.GetService<AppConfigurations>();

                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    context.Response.ContentType = "application/json";
                    context.Response.Headers.Add("Access-Control-Allow-Origin", $"{_config.AngularSiteUrl}");
                    context.Response.Headers.Add("Access-Control-Allow-Headers", "access-control-allow-origin,authorization,content-type");

                    var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
                    if (contextFeature != null) {

                        var ex = contextFeature.Error;

                        var sp = services.BuildServiceProvider();
                        var _logger = sp.GetService<IGenericRepository<Log>>();

                        _logger.AddAndSave(new Log {
                            Description = "Exception not handled occurred",
                            Reason = ex.ToString(),
                            Type = "Error"
                        });

                         await context.Response.WriteAsync(
                            JsonConvert.SerializeObject(new {
                            Status = context.Response.StatusCode,
                            Message = "Internal Server Error."
                        }));
                    }
                });

The code has to be put into in the Configure method of Startup class.

I hope that it could be of some help.

Upvotes: 1

Rameez Rami
Rameez Rami

Reputation: 5728

I found out what was causing the issue.. Its a server side issue. You need to set the CORS middleware first then the remaining API middlewares.

Please note i am working with Laravel 5.6 + Angular 5

Wrong Code

'api' => [ 'throttle:60,1', 'bindings', \Barryvdh\Cors\HandleCors::class, ],

Currect Code

'api' => [ \Barryvdh\Cors\HandleCors::class, 'throttle:60,1', 'bindings' ],

Upvotes: 2

DP3
DP3

Reputation: 128

I found the issue out. When I run the code on my local machine, it always returns status code '0'. When the code is deployed on my cloud server, I am able to derive all the correct status codes and perform corresponding error handling.

Upvotes: 2

tlt
tlt

Reputation: 15211

you need to send your request with option:

{observe:'response'} in order to get full response with headers and status codes exposed

Upvotes: 0

Related Questions