{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/orleans/issues/5205","repository_url":"https://api.github.com/repos/dotnet/orleans","labels_url":"https://api.github.com/repos/dotnet/orleans/issues/5205/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/orleans/issues/5205/comments","events_url":"https://api.github.com/repos/dotnet/orleans/issues/5205/events","html_url":"https://github.com/dotnet/orleans/issues/5205","id":385982451,"node_id":"MDU6SXNzdWUzODU5ODI0NTE=","number":5205,"title":"Exceptions on stream consumers are not logged","user":{"login":"galvesribeiro","id":4714040,"node_id":"MDQ6VXNlcjQ3MTQwNDA=","avatar_url":"https://avatars3.githubusercontent.com/u/4714040?v=4","gravatar_id":"","url":"https://api.github.com/users/galvesribeiro","html_url":"https://github.com/galvesribeiro","followers_url":"https://api.github.com/users/galvesribeiro/followers","following_url":"https://api.github.com/users/galvesribeiro/following{/other_user}","gists_url":"https://api.github.com/users/galvesribeiro/gists{/gist_id}","starred_url":"https://api.github.com/users/galvesribeiro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/galvesribeiro/subscriptions","organizations_url":"https://api.github.com/users/galvesribeiro/orgs","repos_url":"https://api.github.com/users/galvesribeiro/repos","events_url":"https://api.github.com/users/galvesribeiro/events{/privacy}","received_events_url":"https://api.github.com/users/galvesribeiro/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"xiazen","id":20803801,"node_id":"MDQ6VXNlcjIwODAzODAx","avatar_url":"https://avatars3.githubusercontent.com/u/20803801?v=4","gravatar_id":"","url":"https://api.github.com/users/xiazen","html_url":"https://github.com/xiazen","followers_url":"https://api.github.com/users/xiazen/followers","following_url":"https://api.github.com/users/xiazen/following{/other_user}","gists_url":"https://api.github.com/users/xiazen/gists{/gist_id}","starred_url":"https://api.github.com/users/xiazen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiazen/subscriptions","organizations_url":"https://api.github.com/users/xiazen/orgs","repos_url":"https://api.github.com/users/xiazen/repos","events_url":"https://api.github.com/users/xiazen/events{/privacy}","received_events_url":"https://api.github.com/users/xiazen/received_events","type":"User","site_admin":false},"assignees":[{"login":"xiazen","id":20803801,"node_id":"MDQ6VXNlcjIwODAzODAx","avatar_url":"https://avatars3.githubusercontent.com/u/20803801?v=4","gravatar_id":"","url":"https://api.github.com/users/xiazen","html_url":"https://github.com/xiazen","followers_url":"https://api.github.com/users/xiazen/followers","following_url":"https://api.github.com/users/xiazen/following{/other_user}","gists_url":"https://api.github.com/users/xiazen/gists{/gist_id}","starred_url":"https://api.github.com/users/xiazen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiazen/subscriptions","organizations_url":"https://api.github.com/users/xiazen/orgs","repos_url":"https://api.github.com/users/xiazen/repos","events_url":"https://api.github.com/users/xiazen/events{/privacy}","received_events_url":"https://api.github.com/users/xiazen/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/dotnet/orleans/milestones/17","html_url":"https://github.com/dotnet/orleans/milestone/17","labels_url":"https://api.github.com/repos/dotnet/orleans/milestones/17/labels","id":2111063,"node_id":"MDk6TWlsZXN0b25lMjExMTA2Mw==","number":17,"title":"Triage","description":"","creator":{"login":"sergeybykov","id":8248806,"node_id":"MDQ6VXNlcjgyNDg4MDY=","avatar_url":"https://avatars1.githubusercontent.com/u/8248806?v=4","gravatar_id":"","url":"https://api.github.com/users/sergeybykov","html_url":"https://github.com/sergeybykov","followers_url":"https://api.github.com/users/sergeybykov/followers","following_url":"https://api.github.com/users/sergeybykov/following{/other_user}","gists_url":"https://api.github.com/users/sergeybykov/gists{/gist_id}","starred_url":"https://api.github.com/users/sergeybykov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sergeybykov/subscriptions","organizations_url":"https://api.github.com/users/sergeybykov/orgs","repos_url":"https://api.github.com/users/sergeybykov/repos","events_url":"https://api.github.com/users/sergeybykov/events{/privacy}","received_events_url":"https://api.github.com/users/sergeybykov/received_events","type":"User","site_admin":false},"open_issues":103,"closed_issues":564,"state":"open","created_at":"2016-11-03T00:53:47Z","updated_at":"2018-11-30T18:23:35Z","due_on":null,"closed_at":null},"comments":8,"created_at":"2018-11-30T00:12:14Z","updated_at":"2018-12-05T01:57:16Z","closed_at":null,"author_association":"MEMBER","body":"Hey folks!\r\n\r\nI don't know if it the desired behaviour but I noticed that when a grain receives a message and it throw an exception it doesn't even write a a Warning log. It just swallow the exception:\r\n\r\n![image](https://user-images.githubusercontent.com/4714040/49260064-059ce080-f423-11e8-916d-8db9ec5da8f0.png)\r\n\r\nIf I set `FireAndForgetDelivery = false`, then the caller get the exception:\r\n\r\n![image](https://user-images.githubusercontent.com/4714040/49260117-4268d780-f423-11e8-9b1a-47fed2539d81.png)\r\n\r\nThis is my repro code:\r\n\r\n```\r\n[ImplicitStreamSubscription(\"MyStream\")]\r\n    public class ConsumerGrain : Grain, IConsumerGrain\r\n    {\r\n        private readonly ILogger _logger;\r\n\r\n        public ConsumerGrain(ILoggerFactory loggerFactory)\r\n        {\r\n            this._logger = loggerFactory.CreateLogger<ConsumerGrain>();\r\n        }\r\n\r\n        public override async Task OnActivateAsync()\r\n        {\r\n            var provider = this.GetStreamProvider(\"MyProvider\");\r\n            var stream = provider.GetStream<int>(this.GetPrimaryKey(), \"MyStream\");\r\n\r\n            var handles = await stream.GetAllSubscriptionHandles();\r\n            if (handles.Count > 0)\r\n            {\r\n                var tasks = new List<Task>();\r\n                foreach (var handle in handles)\r\n                {\r\n                    tasks.Add(handle.ResumeAsync(this.Consume));\r\n                }\r\n                await Task.WhenAll(tasks);\r\n            }\r\n            else\r\n            {\r\n                await stream.SubscribeAsync(this.Consume);\r\n            }\r\n        }\r\n        public Task Consume(int number, StreamSequenceToken token)\r\n        {\r\n            if (number % 2 == 0)\r\n            {\r\n                this._logger.LogInformation($\"Stream received a message with an even number: {number}\");\r\n\r\n            }\r\n            else\r\n            {\r\n                throw new InvalidOperationException($\"Ops, we got an odd number and that is not cool: {number}\");\r\n            }\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n    }\r\n```\r\n```\r\npublic class PublisherGrain : Grain, IPublisherGrain\r\n    {\r\n        private IAsyncStream<int> _stream;\r\n        private readonly Random _rnd;\r\n        private readonly ILogger _logger;\r\n\r\n        public PublisherGrain(ILoggerFactory loggerFactory)\r\n        {\r\n            this._logger = loggerFactory.CreateLogger<PublisherGrain>();\r\n            this._rnd = new Random();\r\n        }\r\n\r\n        public override Task OnActivateAsync()\r\n        {\r\n            var provider = this.GetStreamProvider(\"MyProvider\");\r\n            this._stream = provider.GetStream<int>(this.GetPrimaryKey(), \"MyStream\");\r\n\r\n            this.RegisterTimer(_ =>\r\n            {\r\n                return _stream.OnNextAsync(this._rnd.Next());\r\n            }, null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(2));\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n        public Task Publish()\r\n        {\r\n            this._logger.LogInformation(\"Running tests!\");\r\n            return Task.CompletedTask;\r\n        }\r\n    }\r\n```\r\n\r\nSo, `FireAndForgetDelivery` makes sense to _ignore_ exceptions on the caller. However, other providers doesn't have that option (nor make sense to). \r\n\r\nShouldn't the stream runtime notify as a Warning that it tried to delivery a message but an exception happened? I know it does that if the consumer grain fail to get activated (i.e. fail on `OnActivateAsync()`) but not on the processing method...\r\n\r\nAny thoughts?"},"comment":{"url":"https://api.github.com/repos/dotnet/orleans/issues/comments/444329495","html_url":"https://github.com/dotnet/orleans/issues/5205#issuecomment-444329495","issue_url":"https://api.github.com/repos/dotnet/orleans/issues/5205","id":444329495,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0NDMyOTQ5NQ==","user":{"login":"galvesribeiro","id":4714040,"node_id":"MDQ6VXNlcjQ3MTQwNDA=","avatar_url":"https://avatars3.githubusercontent.com/u/4714040?v=4","gravatar_id":"","url":"https://api.github.com/users/galvesribeiro","html_url":"https://github.com/galvesribeiro","followers_url":"https://api.github.com/users/galvesribeiro/followers","following_url":"https://api.github.com/users/galvesribeiro/following{/other_user}","gists_url":"https://api.github.com/users/galvesribeiro/gists{/gist_id}","starred_url":"https://api.github.com/users/galvesribeiro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/galvesribeiro/subscriptions","organizations_url":"https://api.github.com/users/galvesribeiro/orgs","repos_url":"https://api.github.com/users/galvesribeiro/repos","events_url":"https://api.github.com/users/galvesribeiro/events{/privacy}","received_events_url":"https://api.github.com/users/galvesribeiro/received_events","type":"User","site_admin":false},"created_at":"2018-12-05T01:57:16Z","updated_at":"2018-12-05T01:57:16Z","author_association":"MEMBER","body":"> Hey sorry I didn't mention, IStreamFailureHandler is only for persistent stream provider, not for SMS. I mentioned it because I thought that it is persistent stream providers are bring troubles to you.\r\n\r\nI meant for all providers. It just happens SMS is the one we are mostly using here for something...\r\n\r\n> Can you explain more on what is the problem? I thought SMS stream provider is fine because if you set fireAndForget to false then you get logging on delivery failures.\r\n\r\nWe have streams that are using SMS provider with `FireAndForgetDelivery = true`. The caller doesn't care about the results and it is fine that it doesn't get an exception. However, the consumer code, if throwing an exception (like in my sample on the issue), the exception is not logger and we will never know that it actually happen. \r\n\r\nJust create a simple silo project and add the code I pasted here on the issue and you will see the behaviour as described.\r\n\r\nWhat I was expecting is that even when `FireAndForgetDelivery` is `true`, the stream runtime would log as a Warning or something else when a stream consumer fail to process the message. "}}
{"actor":{"display_login":"galvesribeiro"}}