Specific exceptions handling - c#

Is there any reason to use specific expetion classes MyException1 and MyException2 in this case?
public static void Main()
{
try
{
TestMethod();
}
catch(Exception ex)
{
Console.Writeline(ex);
}
}
private static void TestMethod()
{
// This method can throw Exception1 and Exception2
}
public class MyException1 : Exception {}
public class MyException2 : Exception {}
I know that it makes sense in case when we have several catch blocks for each exception type. But in this case MyException1 and MyException2 are similar empty. These throwed exceptions will be casted to Exception class in the Main method. Maybe is it better not to create two similar Exception classes with such handling?

The concept behind a catch block is that you handle the exception. If a certain type of exception requires a certain type of handling, it is helpful when that exception has its own class, so it can have its own catch block.
For example, if MyException1 can be safely swallowed while MyException2 is fatal, you could write:
try
{
DoSomethingHard();
}
catch (MyException1 exception1)
{
_log.Write("Warning: small exception, no worries. {0}", exception1.Message);
continue;
}
catch (MyException2 exception2)
{
_log.Write("Fatal: big exception, gotta bail out now. {0}", exception2.Message);
break;
}

Exceptions should be wide rather than deep. Have a different exception for each, erm... exception.
Your example doesn't really show a good example. Perhaps if it was more like:
public static void Main()
{
try
{
TestMethod();
}
catch(Exception ex)
{
Console.Writeline(ex);
}
}
private static void TestMethod()
{
if(..bad configuration)
throw new ConfigurationException("configuration item");
if(missing file)
throw new FileMissingException("filename");
// This method can throw Exception1 and Exception2
}
public class ConfigurationException : Exception {}
public class FileMissingException : Exception {}

If you are using ASP.NET, its so common that you create and use your own Exception handler, in that case, you can to consider specific behavior for each exception in only one method (not catch block in every error prone code blocks), look at this simple example:
public class MyExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
if (context.Exception is SqlException)
{
//do something...
}
else if (context.Exception is HttpListenerException)
{
//do something...
}
else
{
//do something else...
}
}
}

Related

C# Syntax error

Is it Syntax error or compiliing error?
using System;
namespace AAA
{
class MyException : Exception{
}
class My2Exception : MyException{
}
class MainClass
{
public static void Main (string[] args)
{
try{
throw new MyException();
}
catch(Exception e){ // compiler says that this catch all exception occur error? Is it syntax error?
}
catch(MyException m){ // Syntax error
}
}
}
}
Is it kind of syntax error?
Is this error syntax error?
thanks
Since a catch block for type Exception is the least specific exception handler possible, the need to provide a more specific catch block is not only redundant, but in C# it's a compile time error. Thus, in a multi-catch block, you should always specify the most generic catch block last:
using System;
namespace AAA
{
class MyException : Exception
{
}
class MainClass
{
public static void Main (string[] args)
{
try
{
throw new MyException();
}
catch (MyException m)
{
//TODO: something
}
catch (Exception e)
{
//TODO: something
}
}
}
}
Exception is a more general class than MyException that's why you should catch it last.
As mentioned by Shaharyar it a 'semantic error'
try{
throw new MyException();
}
catch(MyException m){
}
catch(Exception e){ // Syntax error
}

How to remove try...catch block from many different functions [duplicate]

This question already has answers here:
Is there a way to catch all unhandled exceptions thrown by a given class?
(6 answers)
Closed 8 years ago.
I have a lot of classes (WCF services) that contain several function. Now I need to handle errors, but I don't want to create a block try ... catch within each function (for error handling).
How can I make try...catch in any class (or something else) so that we catch errors but did not write the same block within each method?
There will always be some duplication of code but you can reduce it to one line
public static class ExceptionHandler
{
public static void Run(Action action)
{
try
{
a();
}
catch(Exception e)
{
//Do Something with your exception here, like logging
}
}
}
and then just call
ExceptionHandler.Run(yourAction);
you can add overloads for functions and what not but this approach is not ideal. As you may want to catch specific exceptions in certain cases.
Since you did not provide code specifically, I will write some sample code to make it more obvious. If you have this:
public class MyClass
{
public void Method1ThatCanThrowException()
{
try
{
// the Method1 code that can throw exception
}
catch (MySpecificException ex)
{
// some specific error handling
}
}
public object Method2ThatCanThrowException()
{
try
{
// the Method2 code that can throw exception
}
catch (MySpecificException ex)
{
// the same specific error handling
}
}
}
So, if you intend to have single place error handling, you can use lambda, and the help of a private method:
private T CheckAndCall<T>(Func<T> funcToCheck)
{
try
{
return funcToCheck();
}
catch (MySpecificException ex)
{
// the old specific error handling
}
}
Notice the use of the Func<T> delegate. This is because you may need to wrap the try-catch logic around some code that can return a value.
Then you can rewrite the above methods like this:
public void Method1ThatCanThrowException()
{
CheckAndCall(
() =>
{
// the Method1 code that can throw exception
return null;
});
}
public object Method2ThatCanThrowException()
{
return CheckAndCall(
() =>
{
// the Method2 code that can throw exception
return someObject;
});
}
For example, rather than having to do this:
public class Program
{
public static string ReadFile(string filename)
{
//A BCL method that throws various exceptions
return System.IO.File.ReadAllText(filename);
}
public static void Main(string[] args)
{
try
{
Console.Write(ReadFile("name.txt"));
}
catch (Exception e)
{
Console.WriteLine("An error occured when retrieving the name! {0}", e.Message);
}
try
{
Console.Write(ReadFile("age.txt"));
}
catch (Exception e)
{
Console.WriteLine("An error occured when retrieving the age! {0}", e.Message);
}
}
}
You could implement a "Try..." method, using the ref or out keyword as appropriate:
public class Program
{
public static bool TryReadFile(string filename, out string val)
{
try
{
val = System.IO.File.ReadAllText(filename);
return true;
}
catch (Exception)
{
return false;
}
}
public static void Main(string[] args)
{
string name, age;
Console.WriteLine(TryReadFile("name.txt", out name) ? name : "An error occured when retrieving the name!");
Console.WriteLine(TryReadFile("age.txt", out age) ? age: "An error occured when retrieving the age!");
}
}
The downside to this approach is that you can't act upon a specific exception, but in the case of simply determining if an operation has or has not succeeded, I find this to be a syntactically clean approach.

Preserving exceptions from dynamically invoked methods

Related
Related
I want to dynamically invoke a MethodInfo object and have any exceptions that get thrown from inside of it pass outward as if it were called normally.
I have two options it seems. They're outlined below.
Option 1 maintains the type of the exception thrown by MyStaticFunction, but the StackTrace is ruined because of the throw.
Option 2 maintains the StackTrace of the exception, but the type of the exception is always TargetInvocationException. I can pull out the InnerException and its type, but that means that I can't write this for example:
try { DoDynamicCall(); }
catch (MySpecialException e) { /* special handling */ }
Option 1:
void DoDynamicCall()
{
MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
try
{
method.Invoke(null, new object[] { 5 });
}
catch (TargetInvocationException e)
{
throw e.InnerException;
}
}
Option 2:
void DoDynamicCall()
{
MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
method.Invoke(null, new object[] { 5 });
}
What I really want is for callers to DoDynamicCall to receive exceptions as if they had called this:
void DoDynamicCall()
{
MyClass.MyStaticFunction(5);
}
Is there a way to get the benefits of both Option 1 and Option 2?
Edit:
The option I wish I had (invented special new C# keyword rethrow on the spot):
void DoDynamicCall()
{
MethodInfo method = /*referencing MyClass method void MyStaticFunction(int x)*/;
try
{
method.Invoke(null, new object[] { 5 });
}
catch (TargetInvocationException e)
{
//Magic "rethrow" keyword passes this exception
//onward unchanged, rather than "throw" which
//modifies the StackTrace, among other things
rethrow e.InnerException;
}
}
This would also eliminate the need for this weirdo, because you could use rethrow e; instead:
try { ... }
catch (Exception e)
{
if (...)
throw;
}
In general, it would be a way to decouple throw; from the requirement "I have to be directly in a catch block."
Here's the solution I came up with. It gets the job done. I'm still interested in other answers as there might be something easier or cleaner.
When you want the functionality of throw; but the exception you want to pass on is not the exception of the current catch block, use throw Functional.Rethrow(e);
Replace try...catch... with Functional.TryCatch
Replace try...catch...finally... with Functional.TryCatchFinally
Here's the code:
//Need a dummy type that is throwable and can hold an Exception
public sealed class RethrowException : Exception
{
public RethrowException(Exception inner) : base(null, inner) { }
}
public static Functional
{
public static Exception Rethrow(Exception e)
{
return new RethrowException(e);
}
public static void TryCatch(Action _try, Action<Exception> _catch)
{
try { _try(); }
catch (RethrowException e) { _catch(e.InnerException); }
catch (Exception e) { _catch(e); }
}
public static T TryCatch<T>(Func<T> _try, Func<Exception, T> _catch)
{
try { return _try(); }
catch (RethrowException e) { return _catch(e.InnerException); }
catch (Exception e) { return _catch(e); }
}
public static void TryCatchFinally(
Action _try, Action<Exception> _catch, Action _finally)
{
try { _try(); }
catch (RethrowException e) { _catch(e.InnerException); }
catch (Exception e) { _catch(e); }
finally { _finally(); }
}
public static T TryCatchFinally<T>(
Func<T> _try, Func<Exception, T> _catch, Action _finally)
{
try { return _try(); }
catch (RethrowException e) { return _catch(e.InnerException); }
catch (Exception e) { return _catch(e); }
finally { _finally(); }
}
}
Update
In .NET 4.5 there is the new System.Runtime.ExceptionServices.ExceptionDispatchInfo class. This can be used to capture an exception:
var capturedException = ExceptionDispatchInfo.Capture(e);
And then later this is used to resume throwing the exception:
capturedException.Throw();
No, I don't believe there is a way to have the benefits of both. However, throwing e.InnerException will still allow you to get the original stacktrace, because you can simply use e.InnerException.StackTrace to get the original stack trace. So, in short, you should use option 1.
The best option is Option 3: don't use reflection at all, but instead use Expression<T>.Compile().
Instead of doing this:
static void CallMethodWithReflection(MethodInfo method)
{
try
{
method.Invoke(null, new object[0]);
}
catch (TargetInvocationException exp)
{
throw exp.InnerException;
}
}
Try to aim for this:
private static void CallMethodWithExpressionCompile(MethodInfo method)
{
Expression.Lambda<Action>(Expression.Call(method)).Compile()();
}
The caveat is that you need to know the method signature, although you can write code that dynamically builds the expression to fit one of several signatures.
You may not always be able to use this technique, but when you do it is the best option. For all intents and purposes it is like calling any other delegate. It is also faster than reflection if you make multiple calls (in this case compile only once and keep a handle on the compiled delegate).
I had a similar issue and came up with this:
/// <summary>
/// Attempts to throw the inner exception of the TargetInvocationException
/// </summary>
/// <param name="ex"></param>
[DebuggerHidden]
private static void ThrowInnerException(TargetInvocationException ex)
{
if (ex.InnerException == null) { throw new NullReferenceException("TargetInvocationException did not contain an InnerException", ex); }
Exception exception = null;
try
{
//Assume typed Exception has "new (String message, Exception innerException)" signature
exception = (Exception) Activator.CreateInstance(ex.InnerException.GetType(), ex.InnerException.Message, ex.InnerException);
}
catch
{
//Constructor doesn't have the right constructor, eat the error and throw the inner exception below
}
if (exception == null ||
exception.InnerException == null ||
ex.InnerException.Message != exception.Message)
{
// Wasn't able to correctly create the new Exception. Fall back to just throwing the inner exception
throw ex.InnerException;
}
throw exception;
}
An Example of it's use is below:
try
{
return typeof(MyType).GetMethod(methodName, BindingFlags.Public | BindingFlags.Static)
.MakeGenericMethod(new[] { myType) })
.Invoke(null, parameters);
}
catch (TargetInvocationException ex)
{
ThrowInnerException(ex);
throw new Exception("Throw InnerException didn't throw exception");
}

using block swallowing exceptions

I have
void foo1()
{
using(...){...}
}
void foo2()
{
using(...){...}
}
void foo3()
{
using(...){...}
}
and I have
void foo()
{
...
backgroundWorker.DoWork += (s, ev) =>
{
try
{
foo1();
foo2();
foo3();
}
catch (Exception ex)
{
// log ex
}
};
...
}
and I just read that using blocks swallow exceptions. It there an elegant way to handle exceptions from foo1(), foo2() and foo3() in foo(). I don't want to have a try/catch inside of each using block in the methods. I did stumble into this post where an extension method is suggested but I'm just checking to see if there is anything better.
FYI, Network disconnection causes the logic inside the using block to throw an exception and that's what I'm trying to handle in one common place.
Thanks,
I think I understand the confusion. Here's some pseudo-code (it may actually execute?) explaining your scenario more simply:
public class Foo
{
public void DoStuff()
{
using (var x = new Thing())
{
throw new ApplicationException("This code breaks");
}
}
private class Thing : IDisposable
{
public override Dispose()
{
throw new ApplicationException("Help, I can't dispose!");
}
}
}
This code can be thought of as the same as this code:
public class Foo
{
public void DoStuff()
{
var x = new Thing();
try
{
throw new ApplicationException("This code breaks");
x.Dispose();
}
catch (Exception err)
{
x.Dispose();
rethrow;
}
}
private class Thing : IDisposable
{
public override Dispose()
{
throw new ApplicationException("Help, I can't dispose!");
}
}
}
By using a using block, you are essentially saying, "No matter what you do, execute Dispose() on this object before moving on." However, the using block doesn't gracefully handle the case when Dispose() fails. Because of this, it never gets around to throwing the inside exception because there was another exception that pre-empted it, even if it occurred afterwards.
Does this make sense? Did I even answer your question? I'm not sure if you're looking for help understanding this or what.
My fear is that Microsoft went down the same rabbit hole here as they did with WCF.
See Avoiding Problems with the Using Statement.
Maybe they should follow their own guidelines.
In almost every (other) case a using block is a best practice.
Youcan try this code to bubble-up and exception from a using statement
Exception exc = null;
using (var x = new object())
{
try
{
// do something x, that causes an exception to be thrown
}
catch(Exception ex) { exc = ex; } // bubble-up the exception
}
if(exc != null) { throw exc; } // throw the exception if it is not null

Return catched exception inside a class method to the caller

I am making a class for using in a winforms application in VC#
My question is how to return a catched exception to the caller out of the class? Take this as an example:
Public Class test
{
private int i = 0;
public test() { }
public SetInt()
{
try
{
i = "OLAGH"; //This is bad!!!
return i;
}
catch (Exception ex)
{
throw ex;
}
}
}
And imagine calling this method in another place while referencing to this class. Is that a good idea? Or how it should be done?
You have several options.
You could not handle the exception at all :
public SetInt()
{
i = "OLAGH"; //This is bad!!!
return i;
}
Then the caller will need to handle the exception.
If you want to handle the exception you can catch the error and handle it.
public SetInt()
{
try
{
i = "OLAGH"; //This is bad!!!
return i;
}
catch (FailException ex)
{
return FAIL;
}
}
Note that it is bad practice to just catch the base Exception class. You should anticipate which errors may occur and try to handle them. Unanticipated errors and the result of bugs and should make a big noise so that you can be alerted to other problems and fix them.
If you want to raise your own kind of exception, you could do :
public SetInt()
{
try
{
i = "OLAGH"; //This is bad!!!
return i;
}
catch (FailException ex)
{
throw new SetIntFailException ( ex );
}
}
Then it is the callers responsibility to handle the SetIntFailException rather than a CastFailException or whatever hundreds of other kind of exceptions your code may throw..
If you want the caller to handle the exception, but you have some clean up you want to do, you can use finally :
public SetInt()
{
try
{
i = "OLAGH"; //This is bad!!!
return i;
}
finally
{
// Cleanup.
}
}
The code in the finally block will always be called, even when there is an exception, but the error still gets raised to the caller.
I am assuming that in your real code, it will at least compile! ;-)
In the first place, the code won't compile.
public class test
{
private int i = 0;
public test(){}
public SetInt(object obj)
{
try
{
i = (int) obj;
return i;
}
catch(exception ex)
{
throw; // This is enough. throwing ex resets the stack trace. This maintains it
}
}
}
If you want to throw an exception do this:
throw new Exception ("My exception");
You can make a class derived from Exception if you want to hold some exception specific details.

Categories