Throwing Exceptions Xamarin c# - c#

I am wondering if i am able to get a method to throw an exception similarly to the below Java code.
private void iAmChecked() throws FileNotFoundException {
FileReader fr = new FileReader("Not Here.txt");
}
I am currently developing an Android Application using Xamarin, I want the app to display a Dialog message if internet connection is lost. I am wrapping the appropriate method calls within the OnCreate with a try catch. The Catch will display a Dialog message and then terminate the application. I am aiming for the methods to throw an error back to the onCreate method so that I can do this.
I am wondering a few points.
Are there better ways of doing this
How can i replicate the above Java code in c#
Will it work
Thanks,
Joe

That code doesn't fires any exception by itself, it only indicates it can throw an exception, but not by itself but by the functions called inside it. On C# that's unnecesary, you don't need to specify what kind of exceptions your code can throw.
There is a better way of doing this:
bool AmIChecked()
{
return System.IO.File.Exists("Not Here.txt");
}

Related

Struggling to understand Xamarin exception handling

I have been crawling the Internet for quite a long time in hope of a solution, and I've come across a number of answers, but none of these seem to achieve what I want.
I'm trying to handle exceptions without causing the app to crash. Rather than the app simply exiting, I would rather capture the exception, present the user with a more user-friendly error (perhaps a messagebox warning) and allow them to continue operation in the app.
Is it possible to stop the app from bailing out?
The way I'm currently attempting to catch this is like the following:
public class Login : Activity
{
int count = 1;
Session mySession;
protected override void OnCreate(Bundle bundle)
{
AndroidEnvironment.UnhandledExceptionRaiser += HandleAndroidException;
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Login);
Button button = FindViewById<Button>(Resource.Id.Login);
string accountCode = Resource.Id.AccountCode.ToString();
string password = Resource.Id.Password.ToString();
// button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
button.Click += delegate
{
throw new Exception("LETS THROW A RANDOM EXCEPTION");
};
}
void HandleAndroidException(object sender, RaiseThrowableEventArgs e)
{
Log.Error("INTERNAL DEBUG", "PLEASE HANDLE MY EXCEPTION!");
e.Handled = true;
System.Console.Write("YOU'VE JUST BEEN HANDLED!");
}
}
As you can see I am throwing a general exception and attempting to catch this with an UnhandledExceptionRaiser. I used this as a reference: http://androidapi.xamarin.com/index.aspx?link=E%3AAndroid.Runtime.AndroidEnvironment.UnhandledExceptionRaiser
I am able to find my message in the "Android Device Logging" tool, however it is being triggered AFTER an unhandled exception error occurs. I think this means something inside of Xamarin is having first crack at the exception and falling over. Surely there has to be a way of stopping this??
I have seen countless examples online where people have been asking similar questions and there has been no clear solution. Some people have offered some solutions, but these don't actually do what I had anticipated.
It is literally mind boggling to me if this cannot be done.
This is my first time using Xamarin and also my first time developing a mobile app so I apologise if I'm being ignorant about anything.
Please help!!!
There is one important thing you have to understand about the nature of an Unhandled exception in Android, there isn't one.... in Android framework which uses Java it's an Uncaught exception which means you can't "handle" it or recover from it like you maybe would in a .Net environment. Xamarin(Mono) internally "handles" those uncaught exceptions by surrounding literally everything with try-catch and raising the Unhandled event but that is besides the point. It is also discouraged to interact with the UI as well for various reasons.
Theoretically there are several "workarounds" for displaying a dialog to the user or restarting the app, none of which I'd recommend on doing. Instead you should surround sensitive areas with try-catch clauses to handle expected exceptions, as for the unexpected one's just use an exception reporting component and update your app after analyzing the reported exceptions.
Also, I would move the event subscription to the Application class but that is a personal preference.
Like so:
public class YourAppClass : Application
{
public override void OnCreate()
{
AndroidEnvironment.UnhandledExceptionRaiser += HandleAndroidException;
}
}

handling errors through the async dll stack

I'm trying to handle errors that are passed through 2 dlls I've created. So Console.exe calls dll 1. dll 1 completes an async MQ message read and the handler calls dll 2. If dll 2 errors it passes the Exception (throw) without a problem. But the dll 1 (async) handler catch the throw from dll 2 and give me an unhandled by user message.. I have followed the msdn code to add in the IAsyncResult to keep the hander alive but the issue persists.
can anyone advise on how I should handle this stack and get the handler error returned to the console.exe program so I can present it to the user. Code below:-
Console.exe (snippet)
try
{
_msmq.MSMQ_GetMessage(_msgPath);
//set up the print of the number of queue messages
Console.WriteLine("Main thread: starting a timer");
Timer t = new Timer(ComputeBoundOp, _msgPath, 0, 2000);
Console.Write("Press any key to continue . . .");
Console.ReadKey(true);
t.Dispose(); // Cancel the timer now
}
catch (MessageQueueException _msgQex)
{
Console.WriteLine("An error occurred with the queue:- " + _msgQex);
}
catch (Exception _ex)
{
Console.WriteLine("An error occurred with the queue:- " + _ex);
}
dll 1
public void MSMQ_GetMessage(string _MQ_Path)
{
try
{
//set the correct message queue
MessageQueue _msgQ = new MessageQueue(_MQ_Path, QueueAccessMode.ReceiveAndAdmin);
//set the format of the message queue
_msgQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(_TwitterStreamFeed) });
_msgQ.ReceiveCompleted += new ReceiveCompletedEventHandler(_msgQ_RecieveCompleted);
IAsyncResult _result = _msgQ.BeginReceive();
_asyncList.Add(_result); // asyncList is a global variable of type System.Collections - > this allows the callback to remain open and therefore nit garbage collected while the async thread runs off on it's own
}
catch (Exception _ex)
{
throw new Exception("_msgQ_get Message threw the following error :- " + _ex);
}
}
//method to process message
public void _msgQ_RecieveCompleted(object sender, ReceiveCompletedEventArgs e)
{
try
{
//queue that have received a message
MessageQueue _mq = (MessageQueue)sender;
//get the messge off the queue
Message _mqmsg = _mq.EndReceive(e.AsyncResult);
//set the values back into a formatted struct
//now process your SQL....
Azure_SQL _azuresql = new Azure_SQL();
_azuresql.writeMessageToStorage((_TwitterStreamFeed)_mqmsg.Body);
//refresh queue just in case any changes occurred (optional)
_mq.Refresh();
//tell MessageQueue to receive next message when it arrives
_mq.BeginReceive();
}
catch (Exception _ex)
{
throw;
}
dll 2
public void writeMessageToStorage(_TwitterStreamFeed _msmq_message_as_TSF)
{
try
{
// now do something with the class - i..e write the values to the database
SqlConnection _azurecon = new SqlConnection(_AzuzeSQLConnection);
SqlCommand _sqlcmd = new SqlCommand();
//Setup the command string to call the stored procedure
//Add the parameter to the parameters collection of the command
blah blah blah......... Do SQL writing to Db
_azurecon.Open();
SqlDataReader _sqldr_tweet_place = _sqlcmd_place.ExecuteReader(CommandBehavior.CloseConnection);
}
//now close things off
_azurecon.Close();
}
catch (Exception _ex)
{
// Throw the error to preserve the original
throw;
}
The reason for this is that, internally, the MessageQueue class is explicitly swallowing the exception. Where the MessageQueue class raises the ReceiveCompleted event, it's inside of a try-catch statement - and the catch block is empty. Suffice it to say, if an exception occurs inside your ReceiveCompleted event handler, _msgQ_RecieveCompleted(), nothing's ever going to know it happened.
I see a couple of options, in order of preference.
Option 1 - Shift where the asynchronous call is made
Since this exception-swallowing behavior only occurs when using BeginReceive(), in MSMQ_GetMessage(), you can switch from using BeginReceive() to just Receive(). Then, make your call to MSMQ_GetMessage() asynchronous and any exception that gets thrown will be propagated as expected.
As a side note, a new(er) alternative for making asynchronous calls is available; the Task<> class. As opposed to the Thread class, Task<> has exception handling functionality built in. It does, however, require Framework 4 or higher. There is a good explanation of it's use described in the answer here.
Option 2 - Use a custom event
If refactoring the asynchronous call isn't an option, you can create a custom event in your class in 'dll 2' and subscribe to that event in 'Console.exe'. So when an exception occurs in _msgQ_RecieveCompleted(), you can raise the event and 'Console.exe' will be notified.
The MessageQueue.BeginReceive() method uses the standard .NET APM (Asynchronous Programming Model) pattern. It is very important to understand how it works to know how to properly deal with exceptions. Be sure to read the MSDN article, there are lots of other googable resources available.
In APM, the callback that tells you that a message was received in executed on a thread-pool thread. Which is a very efficient way to get code to run quickly. It is however also a very troublesome way when something goes wrong. The EndReceive() method call is likely to throw an exception, it does so to tell you that the receive operation could not be completed. A standard exception it will throw is ObjectDisposedException. Which will happen when the MessageQueue object gets disposed. In your case when your program terminates. You need to catch that exception and exit from your event handler, it is an expected exception and signals that nothing more useful is going to happen next since the queue was closed.
Then there's a raft of possible exceptions that can be raised by major mishaps in the message queue plumbing. Plus whatever you do with the message. Looks like you execute some Azure code, plenty of ways that can fall over. If you let such an exception escape from the callback method, like you do, then there's no catch clause anywhere in the call stack that is going to handle the exception. The standard way .NET deals with unhandled exceptions is to raise the AppDomain.UnhandledException event and terminate your program. If you didn't actually implement that event then there's nothing decent to look at to diagnose the reason your program ended, the Windows Error Reporting dialog has no good diagnostic.
Whether or not you should try to handle the exception and prevent the program from terminating is up to you. But it pretty strongly fits the "don't shoot the messenger" pattern, it is very unlikely your program can meaningfully continue to execute when such an exception is raised. It invariably takes a human to fix the problem, like restoring the network connection or fixing the message queue. If you do catch it then the odds that the same exception is raised over and over again is fairly likely. After all, there wasn't anything decent you could do in your code to repair the network.
So the best guidance here is to not try, just make sure that IT staff has a good diagnostic so they can repair the problem. Do implement the AppDomain.UnhandledException and display and log the e.UnhandledException.ToString() value. This will also let you learn the number of ways that your program can fail. There might be some conditions that are common enough to warrant catching, something like a temporary network outage. At that point you'll also know what to do about it, in other words what kind of code to write in the catch clause. There is no possible way you know what to write right now, you should therefore not try.
Last but not least, do note that you got yourself into this pickle because you used BeginReceive() unnecessarily. You've already got a perfectly good thread to do work on. But it doesn't do anything useful, it is stuck in the Console.ReadKey() method. Particularly in .NET 4.5 a very tricky method to call, it prevents other threads from writing anything to the console. So your error reporting won't work, it will deadlock when it tries to use Console.WriteLine() to write a diagnostic.
You might as well use MessageQueue.Read() instead. Now dealing with exceptions is a lot easier since they occur on the same thread. The MessageQueue.SynchronizingObject can also be helpful to get completion callbacks to occur on the main thread, but that only works in a GUI app, not in a console app.

InvokeRequired Exception Handling

I noticed a few strange behaviors in a Windows Forms scenario which involves threads and UI, so, naturally, this means making use of the InvokeRequired property. The situation: my application makes use of a thread to do some work and the thread sends an event into the UI. The UI displays a message based on an Internationalization system which consists of a dictionary with keys. The I18N system cannot find a key in the dictionary and crashes.
Notes: application is in Debug Mode and I have a try-catch over the entire "Application.Run();" back in Program.cs. However, that try-catch is not reached, as what I will discuss here is based on inner Exception handling, but I mentioned it just in case.
So now here comes the fun parts:
Why, for the life of me, does Visual Studio "censor" exception information from me? In the code below, you will see on the if (InvokeRequired) branch, a try-catch. I log the exception. ex.InnerException is NULL and the provided ex.StackTrace is anemic (only 1 step in it). Now if I comment the try-catch and simply let it crash via the Debugger, I get a much ampler stack trace. Why is that?
To make things worse, neither of the two stack traces versions contain any information about the i18N crash. They just say "The given key was not present in the dictionary." and give me a stack trace up to the Invoke declaration.
On the else branch (that is, InvokeRequired == false), if I put a try-catch, I can successfully catch my Exception back to the i18n system. As you can see, I tried to send my exception with InnerException back to the InvokeRequired == true branch. However, even so, InnerException stays NULL there and I cannot access my i18N error.
I am puzzled by all these things and maybe somebody can help shed some light over here. If you got really strong lanterns that is.
Here is the function's code.
private delegate void AddMessageToConsole_DELEGATE (frmMainPresenter.PresenterMessages message);
private void AddMessageToConsole (frmMainPresenter.PresenterMessages message)
{
if (InvokeRequired)
{ //Catching any errors that occur inside the invoked function.
try { Invoke(new AddMessageToConsole_DELEGATE(AddMessageToConsole), message); }
catch (Exception ex) { MSASession.ErrorLogger.Log(ex); }
//Invoke(new AddMessageToConsole_DELEGATE(AddMessageToConsole), message);
}
else
{
string message_text = ""; //Message that will be displayed in the Console / written in the Log.
try
{
message_text = I18N.GetTranslatedText(message)
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
txtConsole.AppendText(message_text);
}
}
Yes, this is built-in behavior for Control.Invoke(). It only marshals the deepest nested InnerException back to the caller. Not so sure why they did this, beyond avoiding reporting exceptions that were raised by the marshaling code and would confuzzle the reader. It was done explicitly, you cannot change the way it works.
But keep your eyes on the ball, the real problem is that the string indeed cannot be found in the dictionary. The reason for that is that your background thread runs with a different culture from your UI thread. Different cultures have different string comparison rules. You either need to give your dictionary a different comparator (StringComparer.InvariantCulture) or you should switch your background thread to the same culture as your UI thread.
Dealing with a non-system default culture in your UI thread can be difficult, all other threads will be started with the system default. Especially threadpool threads are troublesome, you don't always control how they get started. And culture is not part of the Thread.ExecutionContext so doesn't get forwarded. This can cause subtle bugs, like the one you ran into. Other nastiness is, say, SortedList which suddenly becomes unsorted when read by a thread that uses a different culture. Using the system default culture is strongly recommended. Its what your user is likely to use anyway.
The call stack problem is a known issue with Control.Invoke. You lose the call stack. Sorry. This is because it is rethrown on the UI thread using throw ex;.
The best solution would be to replace the background thread with a background Task. Note: this solution is only available for .NET 4.0. The Task class properly marshals exceptions. I wrote a blog entry about reporting progress from tasks, and the code in that blog entry will allow you to catch any UI update errors in the background thread, preserving the original exception and its call stack.
If you can't upgrade to .NET 4.0 yet, there is a workaround. Microsoft's Rx library includes a CoreEx.dll which has an extension method for Exception called PrepareForRethrow. This is supported in .NET 3.5 SP1 and .NET 4.0 (and SL 3 and SL 4). You'll need to wrap your UI updater method with something a little uglier:
private delegate void AddMessageToConsole_DELEGATE (frmMainPresenter.PresenterMessages message);
private void AddMessageToConsole (frmMainPresenter.PresenterMessages message)
{
if (InvokeRequired)
{
// Invoke the target method, capturing the exception.
Exception ex = null;
Invoke((MethodInvoker)() =>
{
try
{
AddMessageToConsole(message);
}
catch (Exception error)
{
ex = error;
}
});
// Handle error if it was thrown
if (ex != null)
{
MSASession.ErrorLogger.Log(ex);
// Rethrow, preserving exception stack
throw ex.PrepareForRethrow();
}
}
else
{
string message_text = ""; //Message that will be displayed in the Console / written in the Log.
try
{
message_text = I18N.GetTranslatedText(message)
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
txtConsole.AppendText(message_text);
}
}
Note: I recommend you start a migration away from ISynchronizeInvoke. It is an outdated interface that is not carried forward into newer UI frameworks (e.g., WPF, Silverlight). The replacement is SynchronizationContext, which supports WinForms, WPF, Silverlight, ASP.NET, etc. SynchronizationContext is much more suitable as an abstract "thread context" for a business layer.
Invoke on a Windows.Forms object causes the function to be invoked on a separate thread. If an Exception is thrown in your invoked function, the Exception is caught and a new TargetInvocationException is thrown.
This TargetInvocationException contains the initial Excpetion in it's InnerException property.
So, try to do it this way:
catch (TargetInvocationException ex) { MSASession.ErrorLogger.Log(ex.InnerException); }
Edit: Also, if you expand the InnerException property in the debugger, you will be able to access it's stacktrace, even if only as plain text.

Exception handling within an Exception in C#

i know this could be a little weird but a doubt is a doubt afterall...
what would happen in the following situation...
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
//so i will handle that exception over here
//and since an exception occurred while sending a mail
//i will log an event with the eventlog
//All i want to know is what if an exception occurs here
//while writing the error log, how should i handle it??
}
}
Thank you.
I would personally wrap the call to write to event log with another try\catch statement.
However, ultimately it depends on what your specification is. If it is critical to the system that the failure is written to the event log then you should allow it to be thrown. However, based on your example, I doubt this is what you want to do.
You can simply catch errors in the error logging method. However I wouldn't personally do that, as broken error logging is a sign your application can't function at all.
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
WriteToLog();
}
}
private void WriteToLog()
{
try
{
// Write to the Log
}
catch(Exception ex)
{
// Error Will Robinson
// You should probably make this error catching specialized instead of pokeman error handling
}
}
Each exception is caught only when inside a try-catch block. You could nest try-catch but is generally not a good idea.
You could add a try-catch block in your catch block as well.
Considering the kind of exceptions when writing to a file (rights, disk space...) I would advice not to handle it in here. If it fails the first time, there's good chance you won't be able to write to the event log that it's not possible to write in the event log...
Let it bubble up and be handled by an upper level try/catch.
Chris S. has the best answer. Placing a try-catch block inside a catch block is very rarely a good idea. and in your case it will just convolute your code. If you check to see if you were successful in writing to your log file here, you will have to do it in every place where you try to write into your log file. You can easily avoid this unnecessary code duplication by having all your individual modules be self contained when it comes to notifying/handling of error conditions within these modules. When sending your mail fails you perform the proper actions inside your catch block to handle this exceptional condition like:
disposing of the contents of your mail object
making sure your socket is closed
writing an entry into your log file to note the error
Inside your catch block just call whatever API you have defined to writing a log entry into your logfile and forget about about the rest. Inside your logging API is where you should handle any logging related exceptional cases (the disk is full, no permission to write to file, file not found, etc...). Your mailing module does not need to know if the logging was successful or not, that responsibility should be delegated to the logging module.
I personally handle this situation using a simple extension method.
public static class MyExtentions
{
public static void LogToErrorFile(this Exception exception)
{
try
{
System.IO.File.AppendAllText(System.IO.Path.Combine(Application.StartupPath, "error_log.txt"),
String.Format("{0}\tProgram Error: {1}\n", DateTime.Now, exception.ToString()));
}
catch
{
// Handle however you wish
}
}
}
The usage is simple:
try
{
...
}
catch(Exception ex)
{
ex.LogToErrorFile();
}
You can then handle the caught exception inside the extension method however you want, or simply don't catch it and let it bubble up to the top. I've found this design to be a simple, reproducible way to handle exceptions throughout the application.
Firstly I would say don't catch "Exception" in catch block. You could instead, for mailing, check for all validity and then catch specific exception(SmtpException, ) that you can do something about(and informing user with a friendly message). Throwing exception from your code and informing the UI about is not a bad idea. If your methods accepts inputs with certain specification and if they are not met, your method should/can throw error and inform user about it.
For exceptions that have no control over, use global handling exception, like Application_Error for web.
Getting Better Information on Unhandled Exceptions Peter Bromberg explains this better.
Also for any privildged resource you are accessing, like eventlogs, make sure you assembly has access to it.
Useful links Build a Really Useful ASP.NET Exception Engine By Peter A. Bromberg
and
Documenting Exceptional Developers By Peter A. Bromberg
For web application look into
Health monitoring
Exception logging
One more thing, if your application goes wrong/ throws error that can't handle( at all) its better to let it go down gracefully and not continue. Application in unstable state is not good idea.

What's a good way for a c# dll to return error to the calling application?

i'm writing a dll which is a wrapper to a access database. and i'm pretty new to c# in general as my background is in web development LAMP with perl, i'm not sure what's a good way to return error to a calling app in case they pass the wrong parameters to my functions or what not.
I have no idea as of now except to probably do some msgbox or throw some exceptions but i don't know where to start looking. Any help or resources would be more than useful :)
thanks~
You probably don't want to display message dialogs from within your dll, that's the job of the client application, as part of the presentation layer.
.Net library assemblies typically bubble up exceptions to the host application, so that's the approach I'd look at.
public static class LibraryClass
{
public static void DoSomething(int positiveInteger)
{
if (positiveInteger < 0)
{
throw new ArgumentException("Expected a positive number", "positiveInteger");
}
}
}
Then it's up to your host application to handle those exceptions, logging and displaying them as appropriate.
try
{
LibraryClass.DoSomething(-3);
}
catch(ArgumentException argExc)
{
MessageBox.Show("An Error occurred: " + argExc.ToString());
}
Wrong parameters are usually handled by throwing a ArgumentException or one of its subclasses.
You want to throw an exception.
See
http://msdn.microsoft.com/en-us/library/ms229007.aspx
for the most common framework exceptions, such as ArgumentException and InvalidOperationException. See also
http://msdn.microsoft.com/en-us/library/ms229030.aspx
Check out Design Guidelines for Class Library Developers: Error Raising and Handling Guidelines
Dlls generally should not create any kind of UI element to report an error. You can Throw (same meaning as raise) many different kinds of exceptions, or create your own and the calling code (client) can catch and report to the user.
public void MyDLLFunction()
{
try
{
//some interesting code that may
//cause an error here
}
catch (Exception ex)
{
// do some logging, handle the error etc.
// if you can't handle the error then throw to
// the calling code
throw;
//not throw ex; - that resets the call stack
}
}
throw new exception?

Categories