Application Halting on intent.PutExtra - c#

I have created a button click handler, code of which goes like this
private void Next_imga2_Click(object sender, EventArgs e)
{
Pothole p = new Pothole();
p.waterLevel = selected;
Intent i = new Intent(this, typeof(createissue4));
try
{
i.PutExtra("issueObj", JsonConvert.SerializeObject(p));
this.StartActivity(i);
}
catch(Exception ex)
{
Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
}
}
My application is stopping on
i.PutExtra("issueObj",JsonConvert.SerializeObject(p));
I can't really understand why this is causing application to stop, when this line occurs the app stops and visual studio automatically starts to debug the app again.
I have tried:
applying the try/catch block so to make sure that it is not an exception that is causing this.
making sure that pothole class object "p" is not null.
making sure that this method is being executed on button click

Write JsonConvert.SerializeObject(p) in the separate line and check whether this line of code is causing issue.
And you can check the application output window, if any crash log availability.
I have tried same kind of code and have not observed any crash.

Related

Wierd C# exception behaviour: exception not caught in special circumstances

I'm programming a dll as extension for a program (Windows 10, Visual Studio Professional 2019). In this dll I have a very weird behaviour. The scenario:
From then 'main' module of the dll (where the callbacks for the application are located) I open a dialog window (own module) which is calling functions in a third module in it's 'Form Shown' event. In this third module I throw an exception (because the user cancelled an action) which I want to catch in the 'main' module.
When I run this dll in VisualStudio debugger (either Debug or Release Configuration, no difference), the Application is started, the dll is loaded and the process described above works like a charm.
When I run the application w/o VisualStudio, the Application is started, the dll is loaded but after throwing the exception it's not caught as before and I get told by the system that an exception was thrown and not caught.
So why does the code work in the IDE environment but not 'standalone'?
The only thing I could imagine was that there are differences in the event handling code of .NET. In the call stack when I stop in the 'Shown' event function, I see that there are calls to "mscorlib.dll!System.Threading.ExecutionContext". Is it possible that outside of VS the dll is in another execution context so that the exception is mislead?
I would appreciate if someone could explain me this behaviour. Again, it's not a matter of debug or release version, it's about the execution environment.
Thanks in advance,
Jörg
EDIT
I hope this clears the scenario:
dll.cs:
// This function is called from the host application
void callback()
{
try
{
Form dialog = new Form();
dialog.ShowDialog();
}
catch (ExceptionType1)
{
...
}
catch (ExceptionType2)
{
...
}
catch
{
...
}
}
dialog.cs
...
// event function for the 'shown' event of Form class
private void SynchronizationDialog_Shown(object sender, EventArgs e)
{
HelperFunction();
}
...
helper.cs
// here the exception is thrown
void HelperFunction()
{
...
if(...)
{
throw new ExceptionType1();
}
...
}
When debugging the dll in VS, the exception thrown in helper.cs is caught by the catch block, which is as expected.
When running the application calling the dll standalone, the exception is not caught.
EDIT
I now can provide an example project (VS2020): ExceptionCatchTest
If you run it in VS, Exception got caught, else not.
I created a test project using your code and was able to reproduce your problem. Looking through the exception's stack trace it seems the windows message processor Control.WndProc for the form is only in the stack while running from visual studio. As a test, I overrode the WndProc method in the form to add a try-catch block around the call to the base method
protected override void WndProc(ref Message m)
{
try
{
base.WndProc(ref m);
}
catch
{
MessageBox.Show("WndProc caught");
throw;
}
}
when running from Visual Studio, a message box appears indicating "WndProc caught". When not running in Visual Studio, this message never appears before the program crashes.
Thinking about it, probably the best solution to your problem would be to instead add a publicly visible enumeration such as public ErrorStatus errorStatus = ErrorStatus.NoError;. Then, instead of throwing and exception, you could use the following code
errorStatus = ErrorStatus.Error1;
DialogResult = DialogResult.Abort;
return;
You could then change your calling function to
void callback()
{
using (Form dialog = new Form())
{
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.Abort)
{
switch (dialog.errorStatus)
{
case ErrorStatus.Error1:
...
break;
case ErrorStatus.Error2:
...
break;
}
}
}
}

WinForms AppCenter Crashes not working when running executable

I have a WinForms application and added AppCenter Crashes Tracking support.
I have also added Crashes delegates Crashes.ShouldProcessErrorReport, Crashes.SendingErrorReport, Crashes.SentErrorReport, Crashes.FailedToSendErrorReport.
and log them to a text file to make sure they are called. For test pursposes I cause an unhandled exception by throwing a StackOverflowException.
When debugging the program under Visual Studio everything works OK, logs are written to the text file, and crashes are sent to AppCenter server.
When running directly debug executable delegates are not called and crashes are not sent.
I have checked and Crashes API is enabled.
Crashes.ShouldProcessErrorReport = (ErrorReport report) =>
{
DataLogger.Error("AppCenter process error");
return true; // return true if the crash report should be processed, otherwise false.
};
Crashes.SendingErrorReport += (object sender, SendingErrorReportEventArgs e) =>
{
// Your code, e.g. to present a custom UI.
string s = e.Report.Exception.StackTrace;
Console.WriteLine(s);
DataLogger.Error("AppCenter sending ", e.Report.Exception);
};
Crashes.SentErrorReport += (object sender, SentErrorReportEventArgs e) => {
// Your code, e.g. to hide a custom UI.
DataLogger.Error("Appcenter successfully sent a crash");
};
Crashes.FailedToSendErrorReport += (object sender, FailedToSendErrorReportEventArgs e) => {
// Your code goes here.
string s = e.Exception.ToString();
Console.WriteLine(s);
DataLogger.Error("AppCenter failed to send " + s);
};
AppCenter.Start("SECRET_KEY", typeof(Analytics), typeof(Crashes));
bool isEnabled = Crashes.IsEnabledAsync().Result;
DataLogger.Error("AppCeneter enabled " + isEnabled);
Application.Run(new MyForm());
Make sure you've read the documentation on how WinForms handles crashes differently. Unless you've disabled default WinForms behavior, with the following line of code, it doesn't truly crash.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
Additionally, StackOverFlowExceptions have some special behavior, for example:
“Starting with the .NET Framework version 2.0, a
StackOverflowException object cannot be caught by a try-catch block
and the corresponding process is terminated by default.”
It might be that it behaves differently when the debugger is attached as part of the special behavior. Even after allowing WinForms to crash, you might need to try with a different type of exception that does not have special rules. And in fact, a specific function is provided to accomplish this:
Crashes.GenerateTestCrash();

Error in CanExecute() - how to get rid of dialog?

I'm trying to handle exceptions in a dialog so that if any exception occurs, the dialog will be closed and the application will not crash. As you can see, I use a simple try-catch block:
IDialogView dialog = null;
try
{
if (_dialogViewModel == null)
{
dialog = ViewFactory.SomeDialog();
_dialogViewModel = new DialogViewModel(dialog);
_dialogViewModel.LoadData();
}
_dialogViewModel.ShowDialog();
}
catch (Exception ex)
{
if (dialog != null)
dialog.Close();
_dialogViewModel = null;
MessageBox.Show("Sorry, there was an error in the dialog.", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
The problem happens when an error occurs in button's CanExecute() event handler. Error is successfully caught, but when I show the MessageBox to the user, CanExecute() executes again, and so the error happens again. In the end it results in application crash.
I've googled some info, and it were said to make sure that there is no exceptions in CanExecute() event handler. But something like this can happen somewhere else, and that's why I want to simply catch ALL exceptions in the dialog entry point without working with every method.
So, my question is: how to destroy the dialog so that after exception catch it won't show again anymore? Close() didn't work, because before closing it still calls CanExecute().
As you found when you googled, you should make sure that a CanExecute handler is a) lightweight and b) never throws an exception. You are running into the main reason for this: a CanExecute will be run repeatedly, and automatically, by the framework. It will run when focus changes, on input events, when databindings change, and in response to a number of other reasons that you have little to no control over.
The problem is: you do have an error, and that error is occurring repeatedly. That means you can choose between crashing, or showing the dialog repeatedly. Or, you can do something about the error.
Your answer: fix the error.
(Your handler as it stands is fine for your other errors. Leave it there. But this particular error, you need to fix right away.)

How can I get WinForms to stop silently ignoring unhandled exceptions?

This is getting extremely irritating. Right now I have a winforms application, and things were not working right, but no exceptions were being thrown as far as I could tell. After stepping through almost all pieces of relevant code, it turns out that an exception was being thrown at the start of my application.
Long story short, in WinForms, being as awesome as it is, if an exception occurs the WinForms library ignores it. No "an unhandled exception has occurred" JIT message is thrown, it just stops processing the current event and goes back to the GUI.
This is causing random bugs, because code to load data isn't being called due to the exception occurring prior to this data being loaded.
To see this in action I created a brand new WinForms application, and entered the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string blah = null;
blah.Trim();
}
}
Press F5 and the form loads without any errors showing, even though a null reference is being thrown.
I then tried to go to my Program.cs main method and add Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); to it. Still my form loads without causing any errors to be thrown.
Even though I know that I can tell VS to break on all exceptions, I find this situation really bad. It causes really wierd issues that are hard to debug in production, and as this is an internal tool I really want to have it so it actually errors out when an exception occurs, and not silently disregards it.
Does anyone know how to do this?
Update: Just to update on things I have learned from the comments.
This does appear to be a 64-bit issue with windows, as I learned from this question which I did not see before posting. In that question it pointed to a Microsoft bug report about this, which had this to say:
Hello,
This bug was closed as "External" because this behavior results from how x64 version of Windows handle exceptions. When a user mode exception crosses a kernel transition, x64 versions of Windows do not allow the exception to propagate. Therefore attached debuggers are unaware of the fact that an exception occured resulting in the debugger failing to break on the unhandled exception.
Unfortunately where is nothing that the Visual Studo team can do to address this, it is the result of operating system design. All feedback regarding this issue should be addressed to the Windows team; however the Windows team considers this to be the "correct" operating system design, and considers the x86 behavior to be "incorrect".
Best Regards,
Visual Studio Debugger
That being said, builds not run through visual studio (or using Ctrl+F5 to run) does seem to show the JIT exception message box EXCEPT if you have the following code in your Program.cs:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
That code will cause windows to ignore the exception.
However, if you (instead) subscribe to the Application.ThreadException event, not only will your exceptions be caught, visual studio's debugger will break on unhandled exceptions!
In your Program.cs' Main function you should also ensure that you've wrapped your call to open the form in a try/catch. Additionally use the AppDomain.UnhandledException to catch exceptions. We also add Application.ThreadException too.
I believe the following will give you hooks into all the exceptions that can be thrown...
static void Main()
{
try
{
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException);
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
var form = new MainForm();
form.ShowDialog();
}
catch (Exception e)
{
HandleUnhandledException(e);
}
finally
{
// Do stuff
}
}
private static void HandleUnhandledException(Object o)
{
// TODO: Log it!
Exception e = o as Exception;
if (e != null)
{
}
}
private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
HandleUnhandledException(e.ExceptionObject);
}
private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
HandleUnhandledException(e.Exception);
}
Try the following.
Handle exceptions in your main application entry point.
Also, manage unhandled thread exceptions using a ThreadExceptionEventHandler
This is the code snippet:
[STAThread]
public static void Main(string[] args)
{
try
{
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
//your program entry point
}
catch (Exception ex)
{
//manage also these exceptions
}
}
private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
ProcessException(e.Exception);
}
An easy fix is not to run under the debugger.
The debugger is masking the exception for some reason. If you run your app normally (Ctrl+F5), you'll get the usual "Unhandled exception has occurred in your application... Continue/Quit?" dialog.
Having experienced this often and identified the issue regarding 64 bit OS and the Form.Load event, I always just make a point of doing all my start up functions in the Form.Shown event. For all practical purposes this is the same thing (aside from a few rare, exceptional circumstances), and the JIT message is produced in the Shown event.

Why is Method.Invoke generating unhandled exceptions? Unable to catch even with TargetInvocationException

I'm trying to use Method.Invoke to call a windows form dialog, have a user perform some selections/interaction and continue execution. This invoke call is happening in an asynchronous method.
While everything works fine, should an error occur on the windows form, an unhandled exception is thrown, even when trying to catch TargetInvocationException or just Exception.
Both forms are in the same winforms project. I realize where are other ways to perform an async call but this is just to illustrate the issue.
The form dialog is as follows:
public partial class FakeDialog : Form
{
public FakeDialog()
{
InitializeComponent();
}
private void btnOK_Click(object sender, EventArgs e)
{
throw new Exception("oh noes!");
this.DialogResult = DialogResult.OK;
this.Close();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
public new DialogResult ShowDialog()
{
base.ShowDialog();
return this.DialogResult;
}
}
And here is the calling code. None if the catch blocks are being executed, even when not debugging (my problem is not debugging exceptions in the IDE as mentioned here. The following results in an unhandled exception).
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MethodInvoker simpleDelegate = new MethodInvoker(InvokeForm);
IAsyncResult tag = simpleDelegate.BeginInvoke(null, null);
simpleDelegate.EndInvoke(tag);
MessageBox.Show("All done");
}
private void InvokeForm()
{
try
{
Type t = typeof(FakeDialog);
MethodInfo showDialogMethod = t.GetMethod("ShowDialog", new Type[] { });
object dialog = Activator.CreateInstance(t);
System.Windows.Forms.DialogResult result = (System.Windows.Forms.DialogResult)showDialogMethod.Invoke(dialog, new object[] { });
MessageBox.Show(result.ToString());
}
catch (TargetInvocationException tie)
{
MessageBox.Show("Tie exception");
}
catch (Exception ex)
{
MessageBox.Show("general exception");
}
}
}
UPDATE:
Strangely, I'm able to catch the exception when running with debugging (I'm sure the IDE is helping here). Running without debugging causes the unhandled exception.
Also, invoking via an async call doesnt seem to make a difference. If i just call InvokeForm() (ignore all the methodInvoker stuff), I can achieve the same result.
Operating on .NET 2.0 using Visual Studio 2008.
Ok, figured it out.
The result from the code was unhandled exceptions. And while using Method.Invoke for a simple method in another class would behave correctly, the environment changes with the source of the exception occurring in a form. A form event. And I eventually found on Microsoft Support that unhandled exceptions in Windows Form events are not propagated up call stack. There's some pretty interesting reasons for this ("Windows Forms applications have a top-level exception handler that allows the program to continue to run if it can recover").
It also gives credence to what Marc mentioned over putting things in the Load event. Sigh. So the reason for all this is pretty obvious now.
As for the code running fine while debugging (as opposed to without), I think I can thank the JIT debugger for that. #fluf pointed to me that specifically enabling the JIT debugger gave the same result as running with debugging. #Marc Gravell, depending on VS settings this might explain only I and fluf could reproduce. There's some more info on it here but it's not a production fix.
So the real solution is either handling the exceptions in the event handlers themselves or use the solution as mentioned in the Microsoft Support article above, which solves my issues.
I can't actually repro from your code, but: the Load event is.... different, and some odd things can happen if you get an exception inside the Load event. Simply my advice would be: move this code out of the Load event. It also doesn't help that attaching a debugger here changes the behaviour (a Heisenbug).
Without seeing MethodInvoker's declaration i can only guess, but it is possible that InvokeForm() method is executed on non-UI thread.
MethodInvoker simpleDelegate = new MethodInvoker(InvokeForm);
IAsyncResult tag = simpleDelegate.BeginInvoke(null, null);
To show a dialog you may consider to rewrite this as follows:
Action simpleDelegate = new Action(InvokeForm);
this.BeginInvoke(simpleDelegate);

Categories

Resources