Good practice design pattern for Exception handling - c#

I have exception handling code in every method for the below code for the bottom level methods
throw new Exception("The error that happens");
Is there any way I can avoid writing this code again and again in each method?
I am trying to write my own code and not using any log frameworks
private void TopLevelMethod()
{
try
{
SomeMethod();
}
catch (Exception ex)
{
// Log/report exception/display to user etc.
}
}
private void SomeMethod()
{
TestPartA();
TestPartB();
TestPartC();
TestPartD();
}
private void TestPartA()
{
// Do some testing...
try
{
if (somethingBadHappens)
{
throw new Exception("The error that happens");
}
}
catch (Exception)
{
// Cleanup here. If no cleanup is possible,
// do not catch the exception here, i.e.,
// try...catch would not be necessary in this method.
// Re-throw the original exception.
throw;
}
}
private void TestPartB()
{
// No need for try...catch because we can't do any cleanup for this method.
if (somethingshappens)
{
throw new Exception("The error that happens");
}
}

Only catch errors if you want to do something meaningful to them such as:
Wrapping the exception with a framework exception (e.g. SqlException. ADO.NET never passes you socket-level errors. It passes you a meaningful SQL error code)
Cleanup
Actually responding (e.g. retry, or insert default values)
Logging is almost never appropriate. The top level handler should log. Certainly not every method in the path should log. What a clutter for logs and for the code. Don't do that.
Simply don't swallow error information and let the error bubble out. That way there is no reason left to insert local logging code for errors everywhere.

If you prefer using Functional Programming like code style one way is to use callback error callbacks.
Example :
private void SomeMethod()
{
// do something
}
public bool Execute(Action act, Action<Exception> onErrorCallback)
{
var res = true;
try
{
act();
}
catch (Exception ex)
{
res = false;
onErrorCallback(ex);
}
return res;
}
And use Execute like this:
var successfull = true;
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
successfull &= Execute(SomeMethod, (ex) => { /* clean up */ });
if (!successfull)
; // show user or something else

Graffito: Would you please give sample code example.Thankyou...
Your code refactored:
private void TopLevelMethod()
{
List<string> errors=new List<string>() ;
if (!SomeMethod(errors)) { /* Log/report errors/display to user etc. */ }
}
private bool SomeMethod(List<string> errors)
{
return TestPartA(errors) && TestPartB(errors) && TestPartC(errors) && TestPartD(errors);
}
private bool TestPartA(List<string> errors)
{
bool result = true ;
try
{
// Do some testing...
if (somethingBadHappens) { result=false; errors.Add("The error that happens"); }
}
catch (Exception ex) { errors.Add("Error in TestPartA: "+Ex.Exception.Message.ToString()) ; }
return result ;
}
private bool TestPartB(List<string> errors)
{
bool result = true ;
// Do some testing...
if (somethingBadHappens) { result = false ; errors.Add("The error that happens"); }
return result ;
}

Related

function that returns two different types

I should have a function that must return either a string of an error (through try / catch) or a different type T.
Example of such a function:
public T get()
{
T struttura;
try {
...
}
catch (Exception xcp) {
return xcp.Message;
}
...
return struttura;
}
There are ways to do this, but really consider if that's what you actually want. It is almost always better just to let the Exception bubble upwards into the calling code.
The first way is to use an out parameter.
public string get(out T result)
{
T struttura;
try{...}
catch (Exception xcp)
{
result = default(T);
return xcp.Message;
}
...
result = struttura;
return String.Empty;
}
The second way is to use a ValueTuple:
public (T, string) get()
{
T struttura;
try{...}
catch (Exception xcp){return (default(T), dexcp.Message);}
...
return (struttura, string.Empty);
}
The .net design guidelines https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/exception-throwing recommend never returning the exception as a return type. It’s always better design to throw the error and catch in the caller.
The guidelines also recommend that if you don’t want to throw the error that you can follow the TryParse pattern https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions-and-performance#try-parse-pattern. Typically you provide both methods, Get and TryGet. The presence of the Try method should indicate to callers that Get will throw exceptions but TryGet won’t. The TryGet also returns a Boolean if the operation was successful, allowing you to handle negative cases without using a try/catch block on the caller.
I suggest TryGet signature:
public bool TryGet(out T struttura) {
try {
...
struttura = ...
...
return true;
}
catch (Exception xcp){
struttura = default(T);
return false;
}
}
Usage:
if (TryGet(out var myStruct)) {
// succeeded, myStruct is returned struttura
}
else {
// failed
}
Or either do not catch exceptions at all or re-throw exception as custom one:
public T Get() {
try {
...
return struttura;
}
catch (Exception xcp) {
throw new MyException("My message", xcp);
}
}
Usage:
try {
myStruct = Get();
}
catch (MyException e) {
// Failed, e.Message for message
Console.WriteLine(e.Message);
}
Finally, you can mechanically combine value and message and return named tuple:
public (T value, string message) Get() {
try {
...
return (struttura, null);
}
catch (Exception xcp) {
return (default(T), xcp.message);
}
}
Usage:
var result = Get();
if (result.message == null) {
// succceded with result.value
}
else {
// failed with result.message
}

Proper way to rethrow an exception

I have the following methods in c#:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
}
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception)
{
//??
}
}
void Method3()
{
//Do something
if(error)
{
throw(new Method3Exception("error"));
}
}
Method3 its gonna be call by different methods and it returns Method3Exception and I need rethrow the exception from Method2 to Method1 but I don't want catch Method3Exception on Method1. what's the best way to do that?
Any suggestions
The term (re)throw usally refer to throwing the exception back to the caller preserving the stack trace (which contains where the exception exactly occurred). This can be done using throw; without specifying the exception operand contrary to throw ex:
try
{
Method3();
}
catch(Method3Exception)
{
throw;
}
However, if you're just going to add a throw with nothing before it in that method. It is useless, just remove the try..catch and the exception is going to propagate to the caller which is the default behavior.
Docs:
A throw statement can be used in a catch block to re-throw the
exception that the catch block caught. In this case, the throw
statement does not take an exception operand.
Alternative way to re-throwing the exception (using throw; as described in other answers) is to wrap the exception in inner exception. As described in MSDN, all custom exceptions should have at least four constructors, and one of them is
public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }
So if all your custom exceptions are like this, you could wrap the exception from Method3 as inner exception:
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception exc)
{
throw new Method2Exception("error", exc); // exc is passed as inner exception
}
}
Then if you want to inspect the inner exception in Method1, you can use property InnerException:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
if(ex.InnerException != null)
{
var message = ex.InnerException.Message;
// Do what you need with the message
}
}
}
In Method2, you can throw a new Method2Exception with the existing Method3Exception as its InnerException:
try
{
Method3();
}
catch(Method3Exception method3Exception)
{
throw new Method2Exception("Message", method3Exception);
}
Then you can catch the Method2Exception above:
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
Exceptions are bubbles up by default. For example,
void FirstMethod()
{
int a = 0;
int b = 10;
int c = b / a;
}
void SecondMethod()
{
FirstMethod();
}
void ThirdMethod()
{
SecondMethod();
}
void FourthMethod()
{
try
{
ThirdMethod();
}
catch (DivideByZeroException ex)
{
// Handle error
}
}
The exception will occur in FirstMethod and it will go upwards and will be cought at ForurthMethod. If you want to log the exception at ThirdMethod for example, but still want your exception to be handled at FourthMethod then you have to options:
First option:
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex)
{
// Log the error
throw; // Throw exception without affecting StackTrace
}
}
Second option:
After C# 6.0 you can do this with ease by using exception filters. Create a logger method which returns false.
bool Log(Exception ex)
{
// Log the error
return false;
}
Add exception filter in third method:
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex) when(Log(ex))
{
// Debugger won't reach here
}
}

Watch for errors without returning error values? More info inside

I am having trouble Googling this, so here is an explanation:
I want to execute a list of methods from another class, one after the other, and have all my error handling take place like a try-catch scenario.
Something like this:
try
{
var thing1 = Worker.GetThing1(); //returns proper value, so continue
var thing2 = Worker.GetThing2(); //throws error with message
var thing3 = Worker.GetThing3(); //doesn't get done, stopped at 2
}
catch (ExceptionError errorMessage)
{
MessageBox.Show(errorMessage);
}
And the functions would look something like:
function GetThing1()
{
if (!success)
{
throw ExceptionError("this is an error message.");
}
}
The problem is I have no idea how to throw exceptions from another class, or if it is even possible to do.
Obviously, this is some serious pseudocode, so if I'm not being clear enough, let me know.
I made a quick console application to illustrate the point. The syntax for throwing a new error is throw new Exception(message); Code:
class Program
{
static void Main(string[] args)
{
try
{
var thing1 = Program.GetThing1(); //returns proper value, so continue
var thing2 = Program.GetThing2(); //throws error with message
var thing3 = Program.GetThing3(); //doesn't get done, stopped at 2
}
catch (Exception errorMessage)
{
Console.WriteLine(errorMessage.Message);
}
Console.ReadKey();
}
private static bool GetThing1()
{
bool success = true;
if (!success)
{
// This will NOT be displayed in the console.
throw new Exception("GetThing1 Error -> Not supposed to see this in output...");
}
return success;
}
private static bool GetThing2()
{
bool success = false;
if (!success)
{
// This WILL be displayed in the console.
throw new Exception("GetThing2 Error -> Expected, this has to be thrown!!!");
}
return success;
}
private static bool GetThing3()
{
bool success = true;
if (!success)
{
// This will NOT be displayed in the console.
throw new Exception("GetThing3 Error - > Not supposed to see this in output...");
}
return false;
}
}
To the guys saying 'all looks fine', please test your statements. Also, there is no standard class called ExceptionError in .NET, you can use the Exception class to catch all types of exceptions (but the poster said that he is using pseudocode, so we cannot hammer on the small details too much).
I think you have created custom exception class, and if your getthings function in diffrunt library than you should move this class to some common library and you should reference to both your libraries.
Thanks for the insight guys, I was so close with my original code. Here is what I ended up with:
class Program
{
static void Main(string[] args)
{
var worker = new Worker();
try
{
worker.GetThing1();
worker.GetThing2();
worker.GetThing3();
}
catch (Exception errorMessage)
{
Console.WriteLine(errorMessage.Message);
}
Console.ReadKey();
}
}
class Worker
{
public void GetThing1()
{
var success = true;
if (!success)
{
throw new Exception("This is an error message!");
}
}
public void GetThing2()
{
var success = false;
if (!success)
{
throw new Exception("This is an error message!");
}
}
public void GetThing3()
{
var success = true;
if (!success)
{
throw new Exception("This is an error message!");
}
}
}
It's so much easier to read and more efficient than trying to catch everything in if-else's. Thanks!

Design Pattern for Error Handling

I've ran into this problem a few times on various projects, and I've wondered if there's a better solution than the one I normally end up using.
Say we have a series of methods that need to execute, and we want to know if something goes wrong within one of the methods and break out gracefully (potentially undo-ing any previous changes...), I typically do the following (pseudo C# because it's what I'm most familiar with):
private bool SomeMethod()
{
bool success = true;
string errorMessage = null;
success = TestPartA(ref errorMessage);
if (success)
{
success = TestPartB(ref errorMessage);
}
if (success)
{
success = TestPartC(ref errorMessage);
}
if (success)
{
success = TestPartD(ref errorMessage);
}
//... some further tests: display the error message somehow, then:
return success;
}
private bool TestPartA(ref string errorMessage)
{
// Do some testing...
if (somethingBadHappens)
{
errorMessage = "The error that happens";
return false;
}
return true;
}
I just wondered (and this is my question) if there's a better methodology for coping with this kind of thing. I seem to end up writing a lot of if statements for something that seems like it should be slicker.
I've been suggested having a loop over a set of delegate functions, but I'd be worried that would be over-engineering the solution, unless there's a clean way to do it.
I think you should probably be using exceptions. Note you should generally only be catching exceptions at the "top level" in your application.
private void TopLevelMethod()
{
try
{
SomeMethod();
}
catch (Exception ex)
{
// Log/report exception/display to user etc.
}
}
private void SomeMethod()
{
TestPartA();
TestPartB();
TestPartC();
TestPartD();
}
private void TestPartA()
{
// Do some testing...
try
{
if (somethingBadHappens)
{
throw new Exception("The error that happens");
}
}
catch (Exception)
{
// Cleanup here. If no cleanup is possible,
// do not catch the exception here, i.e.,
// try...catch would not be necessary in this method.
// Re-throw the original exception.
throw;
}
}
private void TestPartB()
{
// No need for try...catch because we can't do any cleanup for this method.
if (somethingBadHappens)
{
throw new Exception("The error that happens");
}
}
I have used the built-in System.Exception class in my example; you can create your own derived exception classes, or use the built-in ones derived from System.Exception.
You could perhaps try looking at the "Open/Closed" section of the SOLID Principle. In your example you could perhaps create an ITestRule interface which contains a method called CheckRule() that will updated your message and return a bool. You would then create an interface implementation for each rule you want to test, and add that class to a List<ITestRule> object. From the Redmondo example above, I would change to the following:
var discountRules =
new List<ITestRule>
{
new TestPartA(),
new TestPartB(),
new TestPartC(),
new TestPartD(),
};
You would then pass the new List<ITestRule> to an evaluator which will loop through each of the classes and runs the CheckRule() method.
I try to stick to a principle known as 'Fail Fast'; methods should fail when they are supposed to, and return immediately with details of the error. The calling method then responds appropriately (re-throw the exception to its caller, log the details, show an error if it's a UI-bound method, etc): -
http://en.wikipedia.org/wiki/Fail-fast
However, this does not mean using exceptions to control the flow of your application. Just raising an exception when you could deal with it is generally bad practice: -
http://msdn.microsoft.com/en-us/library/dd264997.aspx
In your case, I'd re-write your code as (for example): -
private bool SomeMethod()
{
bool success = false;
try
{
TestPartA();
TestPartB();
TestPartC();
TestPartD();
success = true;
}
catch (Exception ex)
{
LogError(ex.Message);
}
//... some further tests: display the error message somehow, then:
return success;
}
private void TestPartA()
{
// Do some testing...
if (somethingBadHappens)
{
throw new ApplicationException("The error that happens");
}
}

C# How to handle multiple exceptions which does all the same?

In my code I have a method with multiple catch statements, which perform all the same statement. I'm not sure this is the correct way to implement this. How would you do this?
public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
try
{
// Get filename with extension
string file = GetControlFileName(filename);
// Check file exists
if (!File.Exists(file))
throw new FileNotFoundException();
// Load control from file
Control control = LoadControl(filename);
// Check control extends BaseForm
if (control is BaseForm)
{
// Set current application on user control
((BaseForm)control).CurrentApplication = this;
((BaseForm)control).Parameter = parameter;
// Set web user control id
control.ID = filename;
Panel currentPanel = null;
switch (controlDestination)
{
case ControlDestination.Base:
// Set current panel to Base Content
currentPanel = pnlBaseContent;
// Set control in viewstate
this.BaseControl = filename;
break;
case ControlDestination.Menu:
// Set current panel to Menu Content
currentPanel = pnlMenuContent;
// Set control in ViewState
this.MenuBaseControl = filename;
break;
}
currentPanel.Controls.Clear();
currentPanel.Controls.Add(control);
UpdateMenuBasePanel();
UpdateBasePanel();
}
else
{
throw new IncorrectInheritanceException();
}
}
catch (FileNotFoundException e)
{
HandleException(e);
}
catch (ArgumentNullException e)
{
HandleException(e);
}
catch (HttpException e)
{
HandleException(e);
}
catch (IncorrectInheritanceException e)
{
HandleException(e);
}
}
This is how HandleException looks like:
private void HandleException(Exception exception)
{
// Load error control which shows big red cross
LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);
// Store error in database
DHS.Core.DhsLogDatabase.WriteError(exception.ToString());
// Show error in errorbox on master
Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
}
You are doing it right (you should catch only the exceptions you are going to handle and there is no way to catch more than one exception type in one single catch block), but as an alternative, you can just catch(Exception ex), check the exception type, and if it is not one that you expect just throw it again, something like this:
var exceptionTypes=new Type[] {
typeof(FileNotFoundException),
typeof(ArgumentNullException),
//...add other types here
};
catch(Exception ex) {
if(exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
} else {
throw;
}
}
UPDATE: With C# 6 (coming together with Visual Studio 2015) you are able to do the following instead:
catch(Exception ex) when (exceptionTypes.Contains(ex.GetType()) {
HandleException(ex);
}
I'd refactor as follows:-
public class Sample
{
public void LoadControl( ControlDestination controlDestination, string filename, object parameter )
{
HandleExceptions( HandleException, () =>
{
//.... your code
} );
}
private void HandleExceptions( Action<Exception> handler, Action code )
{
try
{
code();
}
catch ( FileNotFoundException e )
{
handler( e );
}
catch ( ArgumentNullException e )
{
handler( e );
}
catch ( HttpException e )
{
handler( e );
}
catch ( IncorrectInheritanceException e )
{
handler( e );
}
}
private void HandleException( Exception exception )
{
// ....
}
}
If I was using VB.NET, I'd use exception filters to do series of catches. But as we're using C#, the approach you have is the most efficient one possible rather than doing
private void HandleExceptions( Action<Exception> handler, Action code )
{
try
{
code();
}
catch ( Exception e )
{
if ( e is FileNotFoundException
|| e is ArgumentNullException
|| e is HttpException
|| e is IncorrectInheritanceException )
handler( e );
else
throw;
}
}
You can use generics for a much nicer solution as long as you don't mind using Lambda's too. I am not a fan of switching on type. I have used this code a few times, I find it comes in especially handy for service proxies in which you want to handle a number of exceptions in the same way. As has been stated above its always best to catch the right type of exception where possible.
The code works by specifying the exceptions as generic type arguments to the handle function. These specific types are then caught but passed to a generic handler as the base class. I didn't add a HandleAndThrow but this can be added as desired. Also change naming to your liking.
public static void Handle<T>(Action action, Action<T> handler)
where T : Exception
{
try
{
action();
}
catch (T exception)
{
handler(exception);
}
}
public static void Handle<T1, T2>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
}
public static void Handle<T1, T2, T3>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
where T3 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
catch (T3 exception)
{
handler(exception);
}
}
public static void Handle<T1, T2, T3, T4>(Action action, Action<Exception> handler)
where T1 : Exception
where T2 : Exception
where T3 : Exception
where T4 : Exception
{
try
{
action();
}
catch (T1 exception)
{
handler(exception);
}
catch (T2 exception)
{
handler(exception);
}
catch (T3 exception)
{
handler(exception);
}
catch (T4 exception)
{
handler(exception);
}
}
}
public class Example
{
public void LoadControl()
{
Exceptions.Handle<FileNotFoundException, ArgumentNullException, NullReferenceException>(() => LoadControlCore(10), GenericExceptionHandler);
}
private void LoadControlCore(int myArguments)
{
//execute method as normal
}
public void GenericExceptionHandler(Exception e)
{
//do something
Debug.WriteLine(e.Message);
}
}
Write it like this:
try
{
// code that throws all sorts of exceptions
}
catch(Exception e)
{
HandleException(e);
}
edit: note that this is a direct answer to your question, not a comment on whether or not this is a recommended practice.
edit2: you can however test in your function if the type of e is a specific list of exceptions and if it's not, you can rethrow it. Exception handling performance is a non-issue since it's meant to be... exceptional in the first place.
I'm going to answer this is in a language-agnostic manner:
1. What you have done now is correct. Nothing wrong with it, except that it might get tedious if you do it many times.
2. Catch the most general form of exception that there is. Simply
catch(Exception e)
{
...
}
3. Maybe you want to only catch some exceptions, without catching all exceptions, which is what you would be doing if you just did #2.
Do what you did in #2, plus modify HandleException to only handle certain types of exceptions. This way you will only ever have to do type tem out once, and it is still more compact than above.
private void HandleException(Exception e) throws Excpetion
{
// Reject some types of exceptions
if (!((e is FileNotFoundException) ||
(e is ArgumentNullException) ||
(e is HttpException ) ||
(e is IncorrectInheritanceException )))
{
throw;
}
//Rest of code
...
}
Edit:
I see Konamiman has an improved version of this third option. I say go for that.
I would do it like this
public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
try
{
// Get filename with extension
string file = GetControlFileName(filename);
// Check file exists
if (!File.Exists(file))
throw new FileNotFoundException();
// Load control from file
Control control = LoadControl(filename);
// Check control extends BaseForm
if (control is BaseForm)
{
// Set current application on user control
((BaseForm)control).CurrentApplication = this;
((BaseForm)control).Parameter = parameter;
// Set web user control id
control.ID = filename;
Panel currentPanel = null;
switch (controlDestination)
{
case ControlDestination.Base:
// Set current panel to Base Content
currentPanel = pnlBaseContent;
// Set control in viewstate
this.BaseControl = filename;
break;
case ControlDestination.Menu:
// Set current panel to Menu Content
currentPanel = pnlMenuContent;
// Set control in ViewState
this.MenuBaseControl = filename;
break;
}
currentPanel.Controls.Clear();
currentPanel.Controls.Add(control);
UpdateMenuBasePanel();
UpdateBasePanel();
}
else
{
throw new IncorrectInheritanceException();
}
}
catch (Exception e)
{
HandleException(e);
}
}
public void HandleException(Exception e)
{
if (e is FileNotFoundException
|| e is ArgumentNullException
|| e is HttpException
|| e is IncorrectInheritanceException)
{
// Load error control which shows big red cross
LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);
// Store error in database
DHS.Core.DhsLogDatabase.WriteError(exception.ToString());
// Show error in errorbox on master
Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
}
}

Categories

Resources