akka.net icon indicating copy to clipboard operation
akka.net copied to clipboard

Ask<object> will not throw exception when the response is Status.Failure

Open ondravondra opened this issue 1 year ago • 3 comments
trafficstars

Version Information Version of Akka.NET? 1.5.15

Describe the bug Ask will not throw exception when the response is Status.Failure

This is caused by the order of case statements in FutureActorRef<T>.TellInternal:

            switch (message)
            {
                case ISystemMessage msg:
                    handled = _result.TrySetException(new InvalidOperationException($"system message of type '{msg.GetType().Name}' is invalid for {nameof(FutureActorRef<T>)}"));
                    break;
                case T t:
                    handled = _result.TrySetResult(t);
                    break;
                case null:
                    handled = _result.TrySetResult(default);
                    break;
                case Status.Failure f:
                    handled = _result.TrySetException(f.Cause
                        ?? new TaskCanceledException("Task cancelled by actor via Failure message."));
                    break;

when T is object and message is Status.Failure the case T t: is executed instead of case Status.Failure f:.

ondravondra avatar Jun 13 '24 09:06 ondravondra

This behaviour can be fixed by reordering the case labels, e.g.:

        {
            switch (reply)
            {
                case T wtv:
                    return wtv;
                case null:
                    return default;
                case Status.Failure fail:
                    throw fail.Cause;
                default:
                    throw new ArgumentException();
            }
        }

        private T GetResult2<T>(object reply)
        {
            switch (reply)
            {
                case Status.Failure fail:
                    throw fail.Cause;
                case T wtv:
                    return wtv;
                case null:
                    return default;
                default:
                    throw new ArgumentException();
            }
        }
        ```
The first method returns the Failure as object but the second method rethrows the exception.

ondravondra avatar Jun 13 '24 09:06 ondravondra

Nice catch! Yes, we should apply your fix and just re-do the case labels here. If you'd like to send in a small PR with a reproduction spec we'd be happy to merge it. We can write something ourselves too - but totally up to you.

Aaronontheweb avatar Jun 13 '24 12:06 Aaronontheweb

reproduction spec we'd be happy to merge it. We can write something ourselves too - but totally up to you.

I am afraid I won't be able to write a PR with tests soon, I am really busy at work, sorry. Thanks for accepting the bug report tho, fixing it will allow us to simplify our company code.

ondravondra avatar Jun 25 '24 10:06 ondravondra