wp-net / WordPressPCL

This is a portable library for consuimg the WordPress REST-API in (almost) any C# application
MIT License
337 stars 129 forks source link

Image upload failing with HttpRequestException #253

Closed audigex closed 3 years ago

audigex commented 3 years ago

I'm getting an "HttpRequestException: Error when copying content to a stream" error when uploading images, but only sometimes.

Strangely, the image appears to upload correctly, but the request fails and I don't get a URL back.

It also seems to succeed several times in a row, and then start failing - I guess the problem is some kind of timeout? But I can't see any obvious way to change this. Any suggestions?

The top exception (System.Exception: Error when uploading image) is my own exception thrown when the task fails, the rest is the inner trace

System.Exception: Error when uploading image
 ---> System.Threading.Tasks.TaskCanceledException: The operation was canceled.
 ---> System.Net.Http.HttpRequestException: Error while copying content to a stream.
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.<WriteSingleChunk>g__CompleteAsync|210_1[TWriteAdapter](ValueTask writeTask, Byte[] bufferToReturn)
   at System.Net.Security.SslStream.WriteAsyncChunked[TWriteAdapter](TWriteAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Security.SslStream.WriteAsyncInternal[TWriteAdapter](TWriteAdapter writeAdapter, ReadOnlyMemory`1 buffer)
   at System.Net.Http.HttpConnection.WriteAsync(ReadOnlyMemory`1 source)
   at System.IO.Stream.CopyToAsyncInternal(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at System.Net.Http.HttpContent.CopyToAsyncCore(ValueTask copyTask)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpContent.CopyToAsyncCore(ValueTask copyTask)
   at System.Net.Http.HttpConnection.SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at WordPressPCL.Utility.HttpHelper.PostRequest[TClass](String route, HttpContent postBody, Boolean isAuthRequired)
   at WordPressPCL.Client.Media.Create(String filePath, String filename, String mimeType)
   at MyProject.Services.MyService.UploadItem(Product product, String imagePath, String fileName)
   --- End of inner exception stack trace ---
   at MyProject.Services.MyService.UploadItem(Product product, String imagePath, String fileName)
   at MyProject.MainWindow.SubmitProductButton_Click(Object sender, RoutedEventArgs e)
ThomasPe commented 3 years ago

Never experienced something like this, perhaps some serverside throtteling? Don't think it has something to do with the library if it works sometimes.

audigex commented 3 years ago

This turned out to be an issue with the client's internet speed and either a timeout, or socket exhaustion due to starting too many uploads before others had finished.

The solution was to implement a better upload queue and have them shout at their ISP...