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()
I had a similar issue with Owin host on Raspberry Pi. This may help https://stackoverflow.com/a/30583109/1786034
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;
}
}
}
Related
I'm using Microsoft Graph API library (C#) and wondering if anyone has experienced this:
Many of my graph API calls time out from time to time.
This can happen to any API call, from getting current user profile to getting sharepoint documents, and so on.
I've tried updating Microsoft Graph API and dependent Nuget packages to the latest versions, but it doesn't help.
To clarify, this application is a Windows console application. On Azure side, it is registered as a native application. As a test application, it is a single-threaded application. No concurrency, race conditions involved. Code logic is as simple as
User logs in.
The program makes a Graph API call (shown in eg.1) to get user's profile and this API call times out.
eg 1.
var currentUser = graphClient.Me.Request().GetAsync().Result;
eg 2.
var site = _graphClient.Sites[SharePointSiteId].Request().GetAsync().Result;
The symptom is after a minute or two, it throws an AggregationException(because of TPL) which includes a TimeOutException.
No unauthorized exception.
I want to know what could be the possible cause and how I can avoid that.
UPDATE:
Here's a screenshot when the exception happens.
UPDATE 2:
I've tried replacing all the API calls to use "await" directly to wait for results. because this example code is a console application. I put
static void Main(string[] args)
{
// using Stephen Cleary's nuget package: Nito.AsyncEx.Tasks
MainImp().WaitAndUnwrapException();
}
static async Task MainImp()
{
// ...
// Graph API calls
This exception is still thrown from this simple API call:
var currentUser = await graphClient.Me.Request().GetAsync();
An unhandled exception of type 'Microsoft.Graph.ServiceException' occurred in mscorlib.dll
Additional information: Code: timeout
Here's the full call stack
at Microsoft.Graph.HttpProvider.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at Microsoft.Graph.HttpProvider.d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
Microsoft.Graph.BaseRequest.d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at Microsoft.Graph.BaseRequest.d__311.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at Microsoft.Graph.UserRequest.<GetAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at SharePointConsoleApp.Program.d__14.MoveNext() in
D:\TestProjects\SharePointConsoleApp\Program.cs:line 133
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at
Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task
task) at SharePointConsoleApp.Program.Main(String[] args) in
D:\TestProjects\SharePointConsoleApp\Program.cs:line 50 at
System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[]
args) at System.AppDomain.ExecuteAssembly(String assemblyFile,
Evidence assemblySecurity, String[] args) at
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Threading.ThreadHelper.ThreadStart()
First of all if it's an application with user interaction you should never do blocking (.Wait() or .Result) calls on the main thread, this will lock-up your application for further user interaction.
So you need to start by using async code, this is a sample of an async Button_Click handler. It will give you a warning, but this seems to be one of the use-cases of an async void.
private async void Button_Click(object sender, RoutedEventArgs
{
var currentUser = await graphClient.Me.Request().GetAsync();
// Presumably do something with the response
labelUser.Text = currentUser.DisplayName;
}
Few days ago I found a nice video about common async/await mistakes
You seem to be talking about a console app running on windows.
As of C# 7.1 you can also have an public static Task Main(string[] args) as starting point. Then your application would look like this:
public static async Task Main(string[] args) {
// Create the client here.....
var graphClient = .....;
// Await every call to the graphclient
var currentUser = await graphClient.Me.Request().GetAsync();
// Do something with the user
}
Maybe the reponse(payload) you get is very huge that while it processes the request times out? I had this issue frequently a while back while I was fiddling with graph api so i used pagination to limit the size/quantity of items sent back by it.
I've just experienced this and the cause was a corporate firewall was blocking traffic to graph.microsoft.com:443
This can be seen in wireshark as [TCP Retransmission]s after the initial request.
Unblocking this host resolved this issue for me.
My WPF application consists of a main TabControl which renders multiple plugins, loaded via MEF. Technically, the ICollectionView of the plugins-collection is bound to the ItemsSource-property of the main TabControl. The IsSynchronizedWithCurrentItem-property is also set to True to keep track of the currently selected tab item.
To initialize the plugins, I subscribe the CurrentChanged-event of the ICollectionView to initialize the selected plugin via lazy loading. Since lots of the initialization tasks are async, I also declared the event handler as async.
private ICollectionView pluginsCv;
public ICollectionView PluginsCv
{
get
{
if (pluginsCv == null)
{
pluginsCv = CollectionViewSource.GetDefaultView(Plugins);
pluginsCv.CurrentChanged += async (sender, args) =>
{
await LoadCurrentSection();
};
}
return pluginsCv;
}
}
Tasks of the LoadCurrentSection-method:
Check if data was already loaded before.
If not, initialize the currently selected plugin, inter alia, reading data via EntityFramework.
LoadCurrentSection-method:
private async Task LoadCurrentSection()
{
// If no tab is selected, select the first one
if (PluginsCv.CurrentItem == null)
{
// Comment for stackoverflow: Another raise of the CurrentChanged-event does not seem to be the cause. Tried to prevent another execution of LoadCurrentSection via a bool flag, an stayed in this method (no return statement). Same result.
PluginsCv.MoveCurrentToFirst();
return;
}
// Get the ViewModel of the currently selected section/plugin
var pluginViewModel = ((IPlugin)PluginsCv.CurrentItem).PluginElement.DataContext as ISettlementScheduleSection;
// Initialize currently selected section/plugin
if (pluginViewModel != null && !pluginViewModel.DataLoaded)
await pluginViewModel.LoadData();
}
LoadData-method of the plugin:
public override async Task LoadData()
{
// ...
Costs = await costsService.GetCosts(SubProjectId, UnitTypeId);
// ...
}
Every plugin holds it's own instances of service-classes for crud operations. Those disposable service classes hold and instance of the db-Context.
Little example:
public class CostsService : ServiceBase
{
public CostsService()
: base()
{ }
public CostsService(MyDbContext db)
{
this.Context = db ?? throw new ArgumentNullException(nameof(db));
}
public async Task<IEnumerable<CostsDefinition>> GetCosts(Guid subProjectId, Guid unitTypeId)
{
return await Context.CostsDefinitions.Where(cd => cd.SubProjectId == subProjectId
&& cd.UnitTypeId == unitTypeId)
.OrderBy(cd => cd.Year).ThenBy(cd => cd.Month)
.ToListAsync();
}
}
The db-context (Context-property) is not static and is also not shared between the plugins.
The Problem: Sometimes, but not always, this way to initialize the plugins causes a System.NotSupportedException: A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe. WPF seems to raise that event multiple times. To me it is unclear in what scenarios it gets raised. When the ICollectionView is first bound to the TabControl and the first item gets automatically selected? Also when I load and insert more plugins into the source collection? ...
Frequency of the bug: In this case, timing seems to play are role. The frequency of that bug changes when running without debugging or under different network conditions.
Workaround attempt: I tried to filter additional/unnecessary calls of the CurrentChanged-handler via a bool flag, but it didn't help in all cases. I just reduced the frequency a bit. I also tried to delegate every access to PluginsCv to the Dispatcher, but it didn't help. Also, I wrote debug information when pluginsCv is null. And I got that information only once, so the CurrentChanged-event must also be subscribed only once.
Exception details:
Source of exception: "EntityFramework"
Stacktrace:
at System.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered()
at System.Data.Entity.Core.Objects.ObjectQuery`1.System.Data.Entity.Infrastructure.IDbAsyncEnumerable<T>.GetAsyncEnumerator()
at System.Data.Entity.Internal.Linq.InternalQuery`1.GetAsyncEnumerator()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Data.Entity.Infrastructure.IDbAsyncEnumerable<TResult>.GetAsyncEnumerator()
at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.ForEachAsync[T](IDbAsyncEnumerable`1 source, Action`1 action, CancellationToken cancellationToken)
at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.ToListAsync[T](IDbAsyncEnumerable`1 source, CancellationToken cancellationToken)
at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.ToListAsync[T](IDbAsyncEnumerable`1 source)
at System.Data.Entity.QueryableExtensions.ToListAsync[TSource](IQueryable`1 source)
at xyz.desk.app.ccm.business.Service.CostsService.<GetCosts>d__7.MoveNext() in D:\Dev\ThatCrazyPluginProject\desk\app\xyz.desk.app.ccm.business\Service\CostsService.cs:line 89
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at xyz.desk.app.ccm.plugin.costplan.constructionprogress.ViewModel.ContructionProgressCostPlanViewModel.<LoadData>d__58.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at xyz.desk.app.ccm.plugin.settlementscheduleshost.ViewModel.SettlementSchedulesHostViewModel.<LoadCurrentSection>d__67.MoveNext() in D:\Dev\ThatCrazyPluginProject\desk\app\xyz.desk.app.ccm.ui\ViewModel\SettlementSchedulesHostViewModel.cs:line 307
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at xyz.desk.app.ccm.plugin.settlementscheduleshost.ViewModel.SettlementSchedulesHostViewModel.<LoadData>d__65.MoveNext() in D:\Dev\ThatCrazyPluginProject\desk\app\xyz.desk.app.ccm.ui\ViewModel\SettlementSchedulesHostViewModel.cs:line 282
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at xyz.desk.app.ccm.ui.ViewModel.ProjectViewModel.<LoadCurrentSection>d__115.MoveNext() in D:\Dev\ThatCrazyPluginProject\desk\app\xyz.desk.app.ccm.ui\ViewModel\ProjectViewModel.cs:line 763
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at xyz.desk.app.ccm.ui.ViewModel.ProjectViewModel.<<get_PluginsCv>b__21_0>d.MoveNext() in D:\Dev\ThatCrazyPluginProject\desk\app\xyz.desk.app.ccm.ui\ViewModel\ProjectViewModel.cs:line 120
Any ideas to solve this issue?
Typical race condition.
Lets consider this scenario
Thread1 - Access PluginsCv
PluginsCv is null so register CurrentChanged
Thread2 - Access PluginsCv
PluginsCv is null so register CurrentChanged
Later...
CurrentChanged fires
Thread1 - await LoadCurrentSection
Thread2 - await LoadCurrentSection
Thread2 "Wait! Thread1 is doing LoadCurrentSection too and its not done yet! Error! Error!"
I'm trying to implement a simple polling service that queries our TFS instance for build results (eventually this will be shown on a build monitor in the office). Following the examples here, I've come up with the following attempt:
var uri = new Uri("http://tfs:8080/tfs/defaultcollection");
var connection = new VssConnection(uri, new VssClientCredentials());
var client = connection.GetClient<BuildHttpClient>();
var builds = await client.GetBuildsAsync(
project: "OurProject",
maxBuildsPerDefinition: 1,
type: DefinitionType.Build);
but the last statement throws a NullReferenceException somewhere deep in the client library (full stack trace at the bottom).
I've tried the following, and it works, but of course it doesn't get me the information I'm looking for :)
var client = connection.GetClient<WorkItemTrackingHttpClient>();
var workItems = await client.GetWorkItemsAsync(ids: new List<int> { 7000, 7005});
Am I fundamentally misunderstanding something about how to query for builds? How do I avoid this exception?
Update: It's not just me!
I just discovered that this error isn't generated (only) on the client side; it's on the server side (too)! A GET request to the following url:
http://tfs:8080/tfs/defaultCollection/OurProject/_apis/build/builds?api-version=2.0&maxBuildsPerDefinition=1&type=build
yields a 500 Internal Server Error response with the following content:
{
"$id": "1",
"innerException": null,
"message": "Object reference not set to an instance of an object.",
"typeName": "System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"typeKey": "NullReferenceException",
"errorCode": 0,
"eventId": 0
}
Given this, how should I troubleshoot? What should I ask/tell the ops people who are running our TFS server? What are we looking for?
Stack trace for the (client-side) exception:
Unhandled Exception: System.AggregateException: One or more errors occurred.
---> Microsoft.VisualStudio.Services.WebApi.VssServiceResponseException: Object reference not set to an instance of an object.
---> System.NullReferenceException: Object reference not set to an instance of an object.
--- End of inner exception stack trace ---
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.HandleResponse(HttpResponseMessage response)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.SendAsync>d__49.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__47`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.SendAsync>d__53`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase.<SendAsync>d__52`1.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task`1.get_Result()
at ConsoleApplication1.Program.Work() in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 32
at ConsoleApplication1.Program.Main(String[] args) in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:line 20
I found the error. Short answer, RTFM :)
It turns out that the maxBuildsPerDefinition parameter is only valid if definitions is also specified. If only the former is given, the server returns 500.
(You could argue that 401 Bad Request would have been a better response, but at least now I know what to do about it.)
My workaround was to do the filtering on the client side instead; I get all builds of all projects, then group by definition and select the latest one:
var builds = await client
.GetBuildsAsync(
project: "OurProject",
type: DefinitionType.Build).Result
.GroupBy(build => build.Definition.Id)
.Select(g => g
.OrderByDescending(build.FinishTime ?? build.StartTime ?? DateTime.MinValue)
.First());
Context
I've written a parallel job framework in C# to import/export a large amount of data from/to an ElasticSearch cluster. To do this I've modelled each import or export of a single item as an object that gets executed at some point by the framework. To interface with ElasticSearch I'm using NEST (official .NET ElasticSearch client library) v1.7.1 and JSON.Net 7.0.1.
Each of the import/export task objects interacts with ElasticSearch using NEST. For performance reasons, I have written a proxy class which groups search requests generated by the task objects into fixed-size batches to use with NEST's _msearch API. The caller to this class is delayed until its batch returns. That class is available here.
My framework wraps models the result of each import/export task as either "bool" or "Exception". The overall process is able to continue even if errors with individual items are encountered.
Problem
I am seeing the following exception raised thousands of times after several hours of tasks completing without errors:
System.InvalidOperationException: Current error context error is different to requested error.
at _____.Matcher.<GetBestMatchAsync>d__15.MoveNext() in C:\\_work\\edc7a363\\_____\\Matcher.cs:line 266
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
_____.MatchBlock`1.<ExecuteAsyncInternal>d__19.MoveNext() in C:\\_work\\edc7a363\\_____\\MatchBlock.cs:line 111
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at _____.Block.BlockBase.<ExecuteAsync>d__11.MoveNext() in C:\\_work\\edc7a363\\_____\\Block\\BlockBase.cs:line 33
This is the code throwing the exception (from the bulk searcher class linked above):
try
{
var bulkResponse = Client.MultiSearch(searchDescriptor);
var items = bulkResponse.GetResponses<T>().ToList();
// Set response values and release all waiting tasks
var zip = currentBuffer.Zip(items, (op, result) => new { op, result });
foreach (var a in zip)
{
a.op.Response = a.result;
a.op.Cts.Cancel();
}
}
catch (Exception e)
{
foreach (var op in currentBuffer)
{
op.Error = e;
op.Cts.Cancel();
}
}
where Client is an IElasticClient.
Googling the exception message leads me to this method in the JsonSerializerInternalBase class in JSON.Net, which seems to be executed after each deserialisation:
private ErrorContext GetErrorContext(object currentObject, object member, string path, Exception error)
{
if (_currentErrorContext == null)
{
_currentErrorContext = new ErrorContext(currentObject, member, path, error);
}
if (_currentErrorContext.Error != error)
{
throw new InvalidOperationException("Current error context error is different to requested error.");
}
return _currentErrorContext;
}
Given a single NEST object is being reused for every operation across multiple threads - and I think NEST only uses one JsonSerializer instance - this makes me think this part of JSON.Net is not thread-safe. Though it's strange how the error doesn't start happening until a few hours into a run.
How can I debug this further?
My colleague eventually traced the error down - it was due to an exception being thrown from inside a JsonConverter which was called by another JsonConverter. The "error context" is an internal JSON.Net thing used to track the last exception thrown. Seems like the exception was handled by the wrong JsonConverter. We added a flag to the inner JsonConverter to let it know not to throw the exception in a certain context.
I hit this error when an enum property was being serialised as null with a custom serialiser, then deserialised with the default deserialiser.
I found this can also happen if you are using the JsonSerializerSettings error handler like this:
parsedResponse = JsonConvert.DeserializeObject<T>(
json,
new JsonSerializerSettings
{
Error = (object sender, ErrorEventArgs args) =>
{
throw new MyCustomException(String.Format("Parse error: {0}", args.ErrorContext.Error.Message));
},
...
The thrown error will not be MyCustomException, but rather the "Current error context error is different to requested error". Apparently Json.NET doesn't like it if you throw an exception inside the error handler
I recently started a Microsoft Band application for Windows Phone 8.1.
The application basically uses UV sensors. But the problem here is not the UV, rather just sending the notification.
The code that sends the notification to the Band looks like (And where it goes to the exception):
await bandClient.NotificationManager.SendMessageAsync(tileGuid, "Title", "Body", DateTimeOffset.Now, MessageFlags.ShowDialog);
The full exception is:
(Exception parameter is below this question)
Handled = false
"Device status code: 0xA0D4000A received"
It is thrown from file App.g.i.cs:
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
I searched the web for this exception, but no result.
Weird part is, that actually at one point this code worked and sent the notification.
It has also sent some exception about "Transport" and "Stream" something, but I cannot re-product those exceptions again right now.
I have done:
Factory reset the Band and reconnect (Unregister and stuff also).
Restart the phone and try other phones.
Moved the notification to be thrown later or earlier in code.
Does anyone happen to have any ideas or such, what could be done and what could be wrong
Exception parameter:
+ Exception {Microsoft.Band.BandOperationException: Device status code: 0xA0D4000A received.
at Microsoft.Band.BandClient.CheckStatus(CargoStatus status, CommandStatusHandling statusHandling)
at Microsoft.Band.BandClient.SendNotification[T](UInt16 notificationId, Guid& tileId, T& notificationInfo, PooledBuffer payload)
at Microsoft.Band.BandClient.SendMessage(Guid& tileId, String title, String body, DateTimeOffset timestamp, MessageFlags flags, CancellationToken token)
at Microsoft.Band.BandClient.<>c__DisplayClass11.<SendMessageAsync>b__10()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Uvicorn.PivotPage.<ThrowNotification>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__3(Object state)
at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()} System.Exception {Microsoft.Band.BandOperationException}
Make sure to verify that the Tile with the GUID passed to the SendMessageAsync() method has first been added to the Band (for example, after a factory reset).
Are you able to send a notification to the band not going through the tile? Just a vibrate notification? Those do not require the tile. I would like to rule out the tile as the issue.