Exception throw behavior - c#

So I have this exception I want to throw if something goes wrong. But it acts strange.
public Calendar LoadCalendar(){
...
if (cal == null)
{
throw new NotImplementedException();
}
_lastPollTime = DateTime.Now;
...
}
I expect this exception to be thrown to wherever LoadCalendar was called. Instead, the program stops at DateTime.Now; because of "NotImplementedException()".
What am I doing wrong? How could I throw it to the end of the method instead?

You need to add a "catch" clause somewhere up the call stack which receives the thrown exception and deals with it somehow.
You could try this in your programs Main function:
static void Main()
{
try
{
// put existing code here
}
catch( Exception e )
{
}
}
Without a catch, the exception has no place to go to and so instead it causes your program to terminate.
These guidlines for working with exceptions might be useful to you: http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET

Just subscribe DispatcherUnhandledException event in App.xaml.cs Class Constructor and you can handle any application exception in this event.
public partial class App : Application
{
public App()
{
this.DispatcherUnhandledException += App_DispatcherUnhandledException;
}
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
////Handle your application exception's here by e.Exception.
}
}

Related

Catching an exception thrown from the click handler of a ContentDialog outside of ShowAsync()

Currently if I throw an exception somewhere down the call stack from the click handler it will crash the application. Is there a way to allow the exception out of the ContentDialog.ShowAsync()?
public async Task<bool> ShowLoginDialogAsync(LogInType loginType) {
var loginDialog = new LoginDialog(loginType);
try {
await loginDialog.ShowAsync(); <-- Exception thrown in click handler will crash the app
}
catch { } <-- I'd like to cach login exceptions here rather than be limited the ContentDialog return result
return loginDialog.Result;
}
public sealed partial class LoginDialog {
private async void OkClicked(ContentDialog contentDialog, ContentDialogButtonClickEventArgs args) {
await Validate(); <-- last chance to catch an exception or crash?
}
}
The OkClicked code doesn't run inside the loginDialog.ShowAsync(), it runs independently. You have to wrap the call to Validate in a try/catch if you want to get the exception from it, or it will just propagate to the context and, uncaught, crash the application.
I've currently decided to use the following strategy in several places to work with converting our WinForms/WPF app to UWP. I wouldn't normally do this and I may choose to factor it out later, but this code allows me to propagate exceptions out of the ContentDialog and abide the async/await pattern:
public sealed partial class LoginDialog {
public Exception Exception { get; private set; }
private async void OkClicked(ContentDialog contentDialog, ContentDialogButtonClickEventArgs args) {
try {
await Validate();
}
catch (Exception e) {
Exception = e;
}
}
}
public async Task<bool> ShowLoginDialogAsync(LogInType loginType) {
var loginDialog = new LoginDialog(loginType);
await loginDialog.ShowAsync();
switch (loginDialog.Exception) {
case null:
break;
default:
throw loginDialog.Exception;
}
return loginDialog.Result;
}

Stop execution of all methods from child method

I am working with a few methods that are called from within other methods, but need to stop processing both methods if an event occurs in the one called from the parent. An example of what I am doing in code would be this:
private void parentMethod()
{
//Do work here
childMethod();
//Do more work here
}
private void childMethod()
{
//Do work (not child labor)
using (var form = new choice(myList))
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
int val = form.listIndex;//values preserved after close
//Do something here with these values
string server = myList2[val - 1];
MyList.Clear();
MyList.Add(server);
}
else
{
Exception e = new Exception("Dialog force closed.",null);
throw e;
}
}
So as you can see here, I tried creating an exception to throw; however, because there are number of other methods getting called from the parent method which also can throw exceptions, but can allow the rest of the code to execute, and the parent method in this example is being called from another method that needs to be stopped as well, how do you stop the execution of multiple methods from within a child method, other that doing Application.Close()?
You need to be more specific in your exception catching. In general, a bare catch is bad practice anywhere except the very top level, as is catch (Exception e) or similar. You should determine which exceptions a method can throw, and then only catch those. Other exceptions will then be passed back up the call stack.
For instance, if you have a method A() that might throw an InvalidOperationException, B() that might throw an ArgumentOutOfRangeException or ArgumentNullException, and C() that might throw an AccessViolationException, your code should look like
public int Main()
{
try
{
try
{
A()
}
catch(InvalidOperationException e)
{
//handle
}
try
{
B()
}
catch(ArgumentOutOfRangeException e)
{
//handle
}
catch(ArgumentNullException e)
{
//handle
}
try
{
C()
}
catch(AccessViolationException e)
{
//handle
}
}
catch (Exception e)
{
//handle all other exceptions
}
}
Now, if any method out of A,B, and C throws an exception you're not expecting, it will be handled by the final catch block.
If you really must have an exception that can only be handled at the top level, it might be a good idea to create your own Exception class:
class MyApplicationException : Exception { }
Then, as long as you never use catch (Exception) anywhere other than at the top level, you will be fine.

Raise exception for Java.Lang.Thread.DefaultUncaughtExceptionHandler

Java.Lang.Thread.DefaultUncaughtExceptionHandler catches only exceptions by the Android runtime. I tried to throw a native exception with
Java.Lang.Integer.ParseInt("xxx");
but the exception is not catched by the DefaultUncaughtExceptionHandler. This is my implementation:
Application subclass:
// OnCreate
UncaughtExceptionHandler uncaughtHandler = new UncaughtExceptionHandler();
uncaughtHandler.UncaughtExceptionHandled += OnUncaughtExceptionHandled;
Java.Lang.Thread.DefaultUncaughtExceptionHandler = uncaughtHandler;
private void OnUncaughtExceptionHandled(object sender, Throwable ex)
{
Console.WriteLine("DefaultUncaughtExceptionHandler");
}
Additional class:
private class UncaughtExceptionHandler : Java.Lang.Object, Java.Lang.Thread.IUncaughtExceptionHandler
{
public event EventHandler<Throwable> UncaughtExceptionHandled;
public void UncaughtException(Java.Lang.Thread thread, Throwable ex)
{
if (UncaughtExceptionHandled != null)
{
UncaughtExceptionHandled(null, ex);
}
}
}
How can I throw an exception that is catched by the DefaultUncaughtExceptionHandler? Is it a good idea to catch unmanaged exceptions in managed code?
You need just a throw new Exception after UncaughtExceptionHandler was initialized
throw new DivideByZeroException();
Is it a good idea to catch unmanaged exceptions in managed code?
Yeap. Crashlytics(Crash Report Library) - works in the same way.

C# transmit exception from class to Form

How can I pass an error in the form of the class. When creating exemplar class.
Class:
class ThreadSafeLog
{
public ThreadSafeLog()
{
try
{
if (!File.Exists(Path_))
{
using (File.Create(Path_)) { }
}
}
catch(Exception e)
{
MessageBox.Show(e.Message);//error transmit exception to Form
}
}
}
Form:
ThreadSafeLog log = new ThreadSafeLog(
#"R:\project\ThreadSafeLog\ThreadSafeLogTest\ThreadSafeLogTest\bin\");
Why would ThreadSafeLog be concerned with what the form that uses it is doing? How is it even supposed to know it's being used by a form? Catch the exception in the form instead.
class ThreadSafeLog
{
public ThreadSafeLog()
{
if (!File.Exists(Path_))
{
using (File.Create(Path_)) { }
}
}
}
Form:
try
{
ThreadSafeLog log = new ThreadSafeLog(
#"R:\project\ThreadSafeLog\ThreadSafeLogTest\ThreadSafeLogTest\bin\");
}
catch (Exception ex)
{
MessageBox.Show(e.Message);
}
Though, as Adriano points out, you may also want to question why you're displaying internal error details directly to users.
I would not notify log's users about an error inside the logger itself. Log is, usually, a subsystem that it's good to consider error-safe and thread-safe or you'll make your code a messy. Imagine:
try
{
// Do something that may fail
}
catch (SomeException e)
{
try
{
logger.Log(e);
}
catch (IOException)
{
// Ooops, log doesn't work. What should I do?
// Should I display a MessageBox?
}
}
Your code will become quickly a messy (imagine to repeat the same check again and again for each trace log).
What I would do is to ignore (if possible) errors inside log function and to take another action instead. How? Just add an event to your log class (code is an example not for production!):
class Logger
{
public event EventHandler<LogErrorEventArgs> Error;
public void Log(Exception e)
{
try
{
// Try to write log somewhere...
}
catch (IOException internalException)
{
EventHandler<LogErrorEventArgs> error = Error;
if (error != null)
error(this, new LogErrorEventArgs(e, internalException);
}
}
}
In this way unhandled errors inside logger will go unnoticed (if this is applicable) or they may be handled (in the way it's appropriate, if there is a way). For example:
Logger logger = new Logger();
logger.Error += delegate(object sender, LogErrorEventArgs e)
{
if (SystemInformation.UserInteractive)
MessageBox.Show(e.ExceptionToLog.Message);
};
You may attach multiple handlers too (for example to log to Windows Log and notify user is session is interactive). When you use log you won't be aware it may fail (so you won't have to fill your code with try/catch everywhere) but if needed you may still be notified and errors inside log will be handled in a consistent manner.
Now let's rewrite the code in our first example like this:
try
{
// Do something that may fail
}
catch (SomeException e)
{
logger.Log(e);
}
Straight, right? I assumed logger will always write an exception (somehow) but it's easy to change code to handle a raw String instead. I omitted code for LogErrorEventArgs because pretty obvious anyway it may look like this:
class LogErrorEventArgs : EventArgs
{
public LogErrorEventArgs(
Exception exceptionToLog,
Exception internalLoggerException)
{
ExceptionToLog = exceptionToLog;
InternalLoggerException = internalLoggerException;
}
public Exception ExceptionToLog
{
get;
set;
}
public Exception InternalLoggerException
{
get;
set;
}
}

ServiceBase.Run, why can't I catch it's exceptions, or react to them in some other way?

I'm calling the following from my entry point static main method:
try { ServiceBase.Run(new MonitorSer()); }
catch (Exception ex) { Console.WriteLine(ex.Message + Process.GetCurrentProcess().MainModule.FileName); }
MonitorSer is an instance of:
class MonitorSer : ServiceBase {
and the entry main method is a member of my class:
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer {
I've had good results catching exceptions for debugging but sometimes they seem to find their own way around my traps, as in this case.
I get a windows box flash up telling me I need to install using installutil when what I really want is to find the name of this process and call it again with the -i switch which I have wired up to make it install intself (credit to those here who contributed/recycled that code).
What makes this more frustrating is that if I set breakpoints upto (or on) the call to ServiceBase.Run, it will fail silently and I am left with the blinking console.
UPDATE
static void Install(bool undo, string[] args)
{
try
{
Console.WriteLine(undo ? "uninstalling" : "installing");
using (AssemblyInstaller inst = new AssemblyInstaller(typeof(MonitorSer).Assembly, args))
{
IDictionary state = new Hashtable();
inst.UseNewContext = true;
try
{
if (undo) inst.Uninstall(state);
else
{
inst.Install(state);
inst.Commit(state);
}
}
catch
{
try
{
inst.Rollback(state);
}
catch { }
throw;
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
}
I clumped the entry point here so I could call the above function, I'll try moving that to another class and setting the entry point there, but I know I can make this entry point (that you, Dmitry, deny) work by calling itself with the appropriate argument to install- which only the BaseService class can do- correct me if I am wrong.
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
Is not your entry point. This will get called once when you install your service using InstallUtil.exe. Entry point can be specified in the project properties and it usually defaults to Program.Main. You should not be starting your service from Installer class.
CLR will let you know of unhandled exceptions if you subscribe to this event:
static void Main() {
...
AppDomain.CurrentDomain.UnhandledException
+= CurrentDomain_UnhandledException;
...
}
private static void CurrentDomain_UnhandledException(
Object sender,
UnhandledExceptionEventArgs e) {
if (e != null && e.ExceptionObject != null) {
// log exception:
}
}
This event provides notification of uncaught exceptions. It allows the
application to log information about the exception before the system
default handler reports the exception to the user and terminates the application
...
Starting with the .NET Framework version 4, this event is not raised
for exceptions that corrupt the state of the process, such as stack
overflows or access violations, unless the event handler is
security-critical and has the
HandleProcessCorruptedStateExceptionsAttribute attribute.
application.
Another place where you might want to log exceptions in windows service (because .NET/SCM will swallow startup exceptions):
protected override void OnStart(String[] args) {
try {
} catch(Exception e) {
// log exception:
throw;
}
}

Categories

Resources