15

I'm running an Owin Selfhost based WebApi where i've put in an API unhandled exception logger via

config.Services.Add(typeof(IExceptionLogger), _apiExceptionLogger);

Relevant part of ApiExceptionLogger:

    public override void Log(ExceptionLoggerContext context)
    {
        if (context == null || context.ExceptionContext == null) return;

        Logger.Error("Unhandled exception from Web API", context.ExceptionContext.Exception);
    }

The cases it's catching and logging regularly are ones where the client requests a dataset and then closes the connection while the results (JSON) are being sent back - people making a request in chrome, and then hitting the X button before all results come back :P

I've pasted a stacktrace below for completeness, just want to know two things:

  • Is this regular/expected behavior? AFAIK it is...I'm running a pretty default API and pipeline
  • Is there any way to handle this? Essentially stop request processing more gracefully in case of a cancellation (the cancellation tokens peppered throughout the request pipeline do come to mind, but doesn't look like they do much in this case, after all the tokens only support co-operative cancellation)

I haven't done any deep dive on the sequence of events happening at the socket level, so far this is only a logging nuisance.

System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException ---> System.Net.HttpListenerException: The I/O operation has been aborted because of either a thread exit or an application request
   at System.Net.HttpResponseStream.EndWrite(IAsyncResult asyncResult)
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.ExceptionFilterStream.EndWrite(IAsyncResult asyncResult)
   --- End of inner exception stack trace ---
   at Microsoft.Owin.Host.HttpListener.RequestProcessing.ExceptionFilterStream.EndWrite(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<SendResponseContentAsync>d__20.MoveNext()    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<SendResponseContentAsync>d__20.MoveNext()
benPearce
  • 37,735
  • 14
  • 62
  • 96
Vivek
  • 2,103
  • 17
  • 26
  • You was lucky to identify the condition when it happens, but I am getting the same exception (with the same stack trace) without any apparent reason. It just happens from time to time in different worker threads. It does not affect anything thought, client is getting response OK. – greatvovan May 18 '17 at 23:50
  • are you not awaiting something maybe? – David McEleney Sep 13 '18 at 10:07

2 Answers2

4

I had a similar issue with Owin host on Raspberry Pi. This may help https://stackoverflow.com/a/30583109/1786034

Community
  • 1
  • 1
zmechanic
  • 1,842
  • 21
  • 27
  • Thanks for looking at this and replying. But the pipeline isn't breaking per se, it's all running fine. I'm catching and logging these in the unhandled exception hook Owin provides, so don't need to swallow and log to keep the pipe running. I guess there's no easy answer then, client disconnects propagate out of HttpListener as exceptions :( – Vivek Jun 04 '15 at 14:19
  • You may try Nowin server (https://github.com/Bobris/Nowin). It apparently doesn't use HttpListener so it might not suffer from this issue. However, It's not ready for production yet. – zmechanic Jun 04 '15 at 22:11
0

Its code issue

Read file async and check.At any time if you are doing an api call and it times out it will definitely throw exception.

using (StreamReader reader = new StreamReader(await selectedFile.OpenStreamForReadAsync()))
            {
                while ((nextLine = await reader.ReadLineAsync()) != null)
                {
                    contents.AppendFormat("{0}. ", lineCounter);
                    contents.Append(nextLine);
                    contents.AppendLine();
                    lineCounter++;
                    if (lineCounter > 3)
                    {
                        contents.AppendLine("Only first 3 lines shown.");
                        break;
                    }
                }
            }
Jin Thakur
  • 2,711
  • 18
  • 15