Hello,
I recently got that curious exception in my Xamarin App on iOS. I currently struggle to symbolicate it properly in HockeyApp but anyway here is the crash reporter log from HA:
Hardware Model: iPhone4,1
Process: trucker_rolspedi [625]
Path: /var/containers/Bundle/Application/B028371C-62B4-4BCD-8491-C78EFE825D22/trucker_rolspediOS.app/trucker_rolspediOS
Identifier: com.rolsped.TruckerApp
Version: 1.1 (60)
Code Type: ARM
Parent Process: ??? [1]Date/Time: 2016-12-04T04:53:09Z
Launch Time: 2016-12-04T04:46:07Z
OS Version: iPhone OS 9.3.5 (13G36)
Report Version: 104-XamarinException Type: SIGABRT
Exception Codes: #0 at 0x21efec5c
Crashed Thread: 0Application Specific Information:
*** Terminating app due to uncaught exception 'System.ArgumentOutOfRangeException', reason: 'System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.'Xamarin Exception Stack:
Parameter name: index
at System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) <0x384df0 + 0x00040> in <15e850188d9f425bbeae90f0bbc51e17#ddbdd0f52c53581cb2d9c691bfe34183>:0
at System.ThrowHelper.ThrowArgumentOutOfRangeException () <0x384b68 + 0x0001b> in <15e850188d9f425bbeae90f0bbc51e17#ddbdd0f52c53581cb2d9c691bfe34183>:0
at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) <0x24a68c + 0x0002f> in <15e850188d9f425bbeae90f0bbc51e17#ddbdd0f52c53581cb2d9c691bfe34183>:0
at Xamarin.Forms.NavigationProxy.Pop () <0x5678b4 + 0x00047> in <f9095492ed2b43559d0236ac22ab7223#ddbdd0f52c53581cb2d9c691bfe34183>:0
at Xamarin.Forms.NavigationProxy.OnPopAsync (System.Boolean animated) <0x567518 + 0x0005b> in <f9095492ed2b43559d0236ac22ab7223#ddbdd0f52c53581cb2d9c691bfe34183>:0
at Xamarin.Forms.NavigationProxy.PopAsync (System.Boolean animated) <0x56708c + 0x0002f> in <f9095492ed2b43559d0236ac22ab7223#ddbdd0f52c53581cb2d9c691bfe34183>:0
at trucker_rolsped.Pages.Media.TaskPhotoUploadPage+d__9.MoveNext () <0xe86944 + 0x013bf> in <3fbc044b4d76429b8dee1ec91e769c22#ddbdd0f52c53581cb2d9c691bfe34183>:0
Here the Code from the root cause Stacktrace line. It must happen at the await Navigation.PopAsync(animated: false)
statement:
private async void SendMediaOnClicked(object sender, EventArgs e) { SendMedia.IsEnabled = false; try { SelectedMedia.DokArt = _dokArt; SelectedMedia.TruckAppId = _truckAppId; UserDialogs.Instance.ShowLoading("Foto wird hochgeladen..."); await AzureBlobStorageManager.Instance.UploadMediaAsync(SelectedMedia); UserDialogs.Instance.HideLoading(); switch (SelectedMedia.MediaState) { case MediaState.Uploaded: if (IsTakenPhoto) { var result = await DisplayAlert("Foto Upload", "Foto wurde erfolgreich hochgeladen. Möchten Sie das Foto jetzt vom Handy löschen?", "Ja", "Nein"); if (result) { //Platform specific file delete var truckerappMedia = SelectedMedia.File.Path; var platformFileHandler = DependencyService.Get<IFileHandling>(); if (platformFileHandler != null) if (await platformFileHandler.FileExistsAsync(truckerappMedia)) { var deleted = await platformFileHandler.DeleteFileAsync(truckerappMedia); if (deleted) UserDialogs.Instance.Toast("Foto wurde erfolgreich hochgeladen und am Handy gelöscht!!", TimeSpan.FromSeconds(value: 2)); else UserDialogs.Instance.Toast("Foto konnte nicht gelöscht werden! Falls Sie das Foto nicht benötigen " + "bitte in der Fotogallery selbst löschen", TimeSpan.FromSeconds(value: 5)); } } } else UserDialogs.Instance.Toast("Upload erfolgreich!", TimeSpan.FromSeconds(value: 2)); break; case MediaState.Queued: UserDialogs.Instance.Toast("Upload erfolgt automatisch wenn Sie wieder mit Internet oder dem mobilem Netz verbunden sind!"); break; case MediaState.Created: await DisplayAlert("Media Info", "Upload MediaState.Created!", "Ok"); break; case MediaState.Error: await DisplayAlert("Media Info", "Upload MediaState.Error!", "Ok"); break; default: await DisplayAlert("Media Info", "Upload MediaState Unknown!", "Ok"); break; } } catch (Exception ex) { SelectedMedia.MediaState = MediaState.Error; await DisplayAlert("Sende Media Fehler", ex.Message, "Ok"); } finally { if (SelectedMedia.MediaState == MediaState.Uploaded) { SelectedMedia?.Dispose(); SelectedMedia = null; } _workflowItem.TruckAuftragWorkFlow.TaskStatusId = 80; await Navigation.PopAsync(animated: false); _tcs.SetResult(true); } }
Here the 2 code areas where I instantiate and use the TakePhotoUploadPage:
1. Usage: From another page called Task40ActionPage
In **Task40ActionPage ** I invoke that method to show the TakePhotoUploadPage :
private async void RejectLoadInTimeClicked(object sender, EventArgs e) { _workflowItem.TruckAuftragLauf.FlagFotoLadezeit = null; try { await ShowPhotoPageAsync(this, _workflowItem); } catch (Exception ex) { await MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(ex); } await Navigation.PopAsync(animated: false); _tcs.SetResult(true); } public async Task<bool> ShowPhotoPageAsync(Page page, WorkflowItem workflowItem) { TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); try { await Navigation.PushAsync(new TaskPhotoUploadPage(tcs, workflowItem, dokArt: "50"), animated: false); } catch (Exception e) { tcs.SetException(e); } return await tcs.Task; }
2. Usage: From an ICommand Action delegate:
public async Task Task50ActionAsync(WorkflowItem workflowItem) { bool isLastWorkItem = false; var page = Application.Current.MainPage.Navigation.NavigationStack.LastOrDefault(); try { if (workflowItem.QuestionYn) { if (page != null) Device.BeginInvokeOnMainThread( async () => { try { bool isOk = await page.DisplayAlert("Todo Command", "Task50ActionAsync ausführen?", "Ja", "Nein"); if (isOk) { await ShowPhotoPageAsync(page, workflowItem, dokArt: "60"); UserDialogs.Instance.ShowLoading("Aufgabe wird gespeichert...", MaskType.Black); isLastWorkItem = await InnerTask50ActionAsync(workflowItem); //PUSH changes to remote.db await OfflineSyncStoreManager.Instance.PushAsync(OfflineSyncStoreManager.Instance.TruckAuftragWorkFlowTable.TableName); if (isLastWorkItem) { // Set TAL to completed workflowItem.TruckAuftragLauf.IsCompleted = true; // Pop Workflow UI View Device.BeginInvokeOnMainThread(async () => await page.Navigation.PopAsync(animated: false)); } UserDialogs.Instance.HideLoading(); } } catch (Exception e) { await MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(e); Device.BeginInvokeOnMainThread( async () => { await page.DisplayAlert("Todo Command Error", $"TaskId={workflowItem.TaskId} Action Error:{e}", "Ok"); }); } }); } else { await ShowPhotoPageAsync(page, workflowItem, dokArt: "60"); UserDialogs.Instance.ShowLoading("Aufgabe wird gespeichert...", MaskType.Black); isLastWorkItem = await InnerTask50ActionAsync(workflowItem); //PUSH changes to remote.db await OfflineSyncStoreManager.Instance.PushAsync(OfflineSyncStoreManager.Instance.TruckAuftragWorkFlowTable.TableName); if (isLastWorkItem) { // Set TAL to completed workflowItem.TruckAuftragLauf.IsCompleted = true; // Pop Workflow UI View Device.BeginInvokeOnMainThread(async () => await page.Navigation.PopAsync(animated: false)); } UserDialogs.Instance.HideLoading(); } } catch (Exception e) { await MetricsManagerHelper.Instance.SendExceptionToApplicationInsights(e); if (page != null) Device.BeginInvokeOnMainThread( async () => { await page.DisplayAlert("Todo Command Error", $"TaskId={workflowItem.TaskId} Action Error:{e}", "Ok"); }); } } public async Task<bool> ShowPhotoPageAsync(Page page, WorkflowItem workflowItem, string dokArt) { TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); try { await page.Navigation.PushAsync(new TaskPhotoUploadPage(tcs, workflowItem, dokArt: dokArt), animated: false); } catch (Exception e) { tcs.SetException(e); } return await tcs.Task; }
Thanks to everyone with helpful suggestions in advance,
Eric
Answers
Hi Eric, did you find a solution?
I have the same issue. @EricBrunner can you explain how you are checking? This is crash is driving me crazy because I cannot reproduce it. Thanks.
// Sometimes NavStack.Count == 0. (XF bug)
if (await IsNavStackInvalid())
return;
await Navigation.PopAsync(animated: false);
private async Task<bool> IsNavStackInvalid()
{
int currentNavigationStackCount = Navigation.NavigationStack.Count;
if (currentNavigationStackCount <= 1)
{
// see curious error: https://rink.hockeyapp.net/manage/apps/460391/app_versions/36/crash_reasons/165742824
Dictionary<string, string> telemetryDictionary = new Dictionary<string, string>();
List<string> pageStack = new List<string>();
foreach (var page in Navigation.NavigationStack)
{
string pageClassName = page.GetType().Name;
pageStack.Add(pageClassName);
}
telemetryDictionary.Add("pageStack", JsonConvert.SerializeObject(pageStack));
await MetricsManagerHelper.Instance.SendGenericMessageToApplicationInsightsAsync(
"Error-Task70PhotoUploadNavStack",
$"Navigationstack Count == {currentNavigationStackCount}. User get automatically navigated back to TA Overview (root).", telemetryDictionary);
await DisplayAlert(
await LanguageMapper.Instance.GetTextAsync(LanguageMapping.TagAlertIntNaviErrorTitle),
await LanguageMapper.Instance.GetTextAsync(LanguageMapping.TagAlertIntNaviErrorText),
await LanguageMapper.Instance.GetTextAsync(LanguageMapping.TagAlertOk));
_tcs.TrySetResult(false);
return true;
}
return false;
}
Thank you @EricBrunner . What is the behavior when the stack is empty? You still return to the previous page? Also, your code does not compile, List is missing the type e.g. List
I had that issue only on deployed apps running in the field and only on Android. Never on iOS. I personally never had that while development.
I just had the same problem. In my case it was caused my this line:
Resolved it like this: