dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.58k stars 10.06k forks source link

Intercept HTTP errors in SignalR JavaScript Client #39079

Open Wwwolfgang opened 2 years ago

Wwwolfgang commented 2 years ago

This is more of a question then a issue. I'm using the @microsoft/signalr (v.6.0.0) javascript client in my Vue project. This is my Connection Builder

client = new HubConnectionBuilder() .withUrl('/chat', { accessTokenFactory: () => IdService.getToken() }) .configureLogging(LogLevel.None) .withAutomaticReconnect() .build()

Later when I start the connection: client.start().then(() => { console.log('Connected') }).catch((err) => { console.error(err) })

What I would like to do is, if there is a error in the moment of starting the connection, I would like to know the HTTP status code from the catched error. Like this: client.start().then(() => { console.log('Connected') }).catch((err) => { console.error(err.response.status) })

The problem is, the error that is getting catched is only a string. Of course I could filter the status code from the string but that seems wrong. So my question is, is there any way or method to get the error codes?

BrennanConroy commented 2 years ago

We sometimes throw an HttpError which has the status code included in it. There might be some improvements we can do here to more consistently throw those errors though.

What specific error are you getting back?

rafikiassumani-msft commented 2 years ago

@BrennanConroy After doing a little bit of research, I think there are places where we may need to consider returning an error type with both the message and status code. One of those areas could be during the actual connection negotiation. See the following area. Notice that when we get a status code that's not 200, we reject the promise with the vanilla js Error class.

https://github.com/dotnet/aspnetcore/blob/c41741805eadf18986a4182f7fe7fd137318f691/src/SignalR/clients/ts/signalr/src/HttpConnection.ts#L331

  Promise.reject(new Error(`error message ${statusCode}`));

We might consider rejecting with a complex Errror Type Object that allows setting both the status code and the error message as you have mentioned above. There are, however, numerous places to change.

     Promise.reject(new HttpError("error message",  statusCode));
Wwwolfgang commented 2 years ago

In my case I was getting an error with 401 error code, because my Bearer Token was expired on the backend. But if I want to react properly to the error in the frontend, my only option is to check if the error string contains '401' and proceed from there. And checking for a error code in a string feels wrong.

ghost commented 2 years ago

Thanks for contacting us. We're moving this issue to the .NET 7 Planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

flensrocker commented 2 years ago

I would also like to intercept "401 Unauthorized" in my Angular app, because I then show a login dialog and after that retry the request. A proper status code in the error object would be great!

Thanks!

ghost commented 2 years ago

Thanks for contacting us.

We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

JunkyXL86 commented 1 year ago

How do people deal with errors at the moment? Is there an alternative solution that does not require parsing the status code?

NechiK commented 1 year ago

@JunkyXL86 I'm using the next temporary approach. That's only way I came up with )

if (error.message && error.message.includes(`Status code '401'`)) {
  this.authService.refreshToken().subscribe();
}
NechiK commented 1 year ago

I just installed @microsoft/signalR version 8 and the connection still doesn't return status codes for the 401 connection error.