Open NaNgets opened 6 months ago
That code sample is pointing at the wrong SignalR implementation. Did you intend to file an issue on https://github.com/SignalR/SignalR? If yes, I can tell you that implementation in not being evolved anymore.
My bad, I'll have to look further for the correct implementation in the current code, will update the issue ASAP.
If you're going to update the issue, I'd suggest also explaining the "why". I have no idea what you are trying to accomplish from reading this issue.
As I said - two scenarios I want to handle:
1) Enable returning errors without throwing them. As you know - throw
has some effect on the efficiency of the call. In the API we can return an ActionResult which will result in an HTTP error, so why not return a type which will be processed and handled as an error? Thus enabling to 'return' the error without throwing it.
2) Enable multiple types return. I have a class, e.g. ActionResult<T1, T2>
, which on API returns the type which is filled, only one (T1 or T2). In signalR I can't return that type because it will be parsed with properties I don't need\want. So I would like to be able to return a dynamic type but without the dynamic
keyword, something more strong-typed, in which I might have something like GetResult
which will either return the type or an error, and be handled accordingly.
@davidfowl updated.
Enable returning errors without throwing them. As you know - throw has some effect on the efficiency of the call. In the API we can return an ActionResult which will result in an HTTP error, so why not return a type which will be processed and handled as an error? Thus enabling to 'return' the error without throwing it.
You can do this already without changes to the protocol or code. Return an object with 2 values.
Enable multiple types return. I have a class, e.g. ActionResult<T1, T2>, which on API returns the type which is filled, only one (T1 or T2). In signalR I can't return that type because it will be parsed with properties I don't need\want. So I would like to be able to return a dynamic type but without the dynamic keyword, something more strong-typed, in which I might have something like GetResult which will either return the type or an error, and be handled accordingly.
I'm not understanding this part.
Can you share a code sample for what you want to write on the server and client using the existing SignalR APIs (Using the JavaScript client)? That would also help us understand if there's an associated protocol change required.
FWIW: The wire protocol is documented here https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/HubProtocol.md. I'm not sure yet how your proposal affects either the API or the wire protocol based on your description.
My proposal doesn't affect the API or the wire protocol, it affects the DefaultHubDispatcher in which it will allow for more fine-grained return types.
I want to be able to return an error and it will be treated as an error, instead of throwing it, how is returning an object with 2 values does that?
In my view, having a new interface called IHubInvocationMessageConvertable
which will have a method called ConvertToMessage()
which will return a HubMessage, and if the return type is this new interface then the DefaultHubDispatcher should send it instead of wrapping it.
e.g.:
public MyMessageClass : IHubInvocationMessageConvertable
{
public Exception? _error;
public int? _item1;
public string? _item2;
...
public HubMessage ConvertToMessage()
{
if (this._error != null)
{
return CompletionMessage.WithError(...);
}
if (this._item1 != null)
{
return CompletionMessage.WithResult(this._item1);
}
if (this._item2 != null)
{
return CompletionMessage.WithResult(this._item2);
}
// return error here...
}
}
public async Task<MyMessageClass> MyTask(int num)
{
if (num < 0)
{
return new MyMessageClass(error: new OutOfRangeException(...));
}
if (num == 0)
{
return new MyMessageClass(item2: "The number is 0");
}
return new MyMessageClass(item1: num * 2);
}
And in DefaultHubDispatcher if the item is of the interface type, call the convert method, override the invocation ID and send it.
This allows me full control of the returned result or error.
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
No response
Describe the solution you'd like
Currently you can only return a type and in the DefaultHubDispatcher it forwards it to a CompletionMessage while indicating the result or error.
This way, we can't return a type which should be handled as an error (like an error action result) so to eliminate the use of
throw
, nor we can return an object which will decide the return type upon processing (e.g. type unions such as in OneOf package).I suggest we support another general return type of CompletionMessage whilst overriding the
InvocationId
(or create a new class with similar properties for result and error) which will allow this sort of behavior.This will allow the application to better control the returned data (result or error).
Additional context
No response