We're struggling with a policy to correctly handle exceptions in our application. Here's our goals for it (summarized):
Handle only specific exceptions.
Handle only exceptions that you can correct
Log only once.
We've come out with a solution that involves a generic Application Specific Exception and works like this in a piece of code:
try {
// Do whatever
}
catch(ArgumentNullException ane)
{
// Handle, optinally log and continue
}
catch(AppSpecificException)
{
// Rethrow, don't log, don't do anything else
throw;
}
catch(Exception e)
{
// Log, encapsulate (so that it won't be logged again) and throw
Logger.Log("Really bad thing", e.Message, e);
throw new AppSpecificException(e)
}
All exception is logged and then turned to an AppSpecificException so that it won't be logged again. Eventually it will reach the last resort event handler that will deal with it if it has to.
I don't have so much experience with exception handling patterns... Is this a good way to solve our goals? Has it any major drawbacks or big red warnings?
Note: One of the drawbacks of this is that after the first catch you lose the ability to handle an specific exception (if you call a method that calls another method and the second one throws an exception you're not able to handle it) but I've found I've never done this any way ... I only handle exceptions with one level of depth ...
If you log the exception too near the time it is first thrown, you won't be logging the full stack trace.
Handle exceptions (that is, fix them), as close as possible to when they were thrown. Gather information about the context as soon as possible to when they were thrown. But allow exceptions to propagate up to where they can actually be handled. Logging is a last-resort sort of handling, so it should occur in the outer layers of application subsystems.
This should eliminate the need for an application-specific exception used as a marker to not log an exception which shouldn't have been caught to begin with.
Don't log an exception and then re-throw it - it is the callers responsibility to handle / log any exceptions that you generate.
Only catch an exception to handle it (for example to log it), or add context specific information.
This is a quite common approach to solve the exception handling problem (from more specific to less specific).
Just bear in mind that having one generic ApplicationSpecific exception to catch everything that happens in that application/method is not a great idea if you want to catch specific problems.
Eventually try extending it with more specific exceptions.
Rethrowing exceptions is good, better is declaring the method to throw certain exceptions and let callers handle them. This way you'll have to create less code and you could centralize some controls.
First option to solve the stack trace problem:
class AppSpecificException : ApplicationException
{
public string SpecificTrace { get; private set; }
public string SpecificMessage { get; private set; }
public AppSpecificException(string message, Exception innerException)
{
SpecificMessage = message;
SpecificTrace = innerException.StackTrace;
}
}
I had to write an example to understand the question and check the stacktrace problem, this is the code to me, put attention to the button2_click method, finally my textbox show the crash string and the stacktrace:
private String internalValue;
private void Operation1(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
}
private void Operation2(Object pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = Convert.ToInt32(pField).ToString();
}
private void Operation3(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
Operation2(-1);
}
/// <exception cref="AppSpecificException"><c>AppSpecificException</c>.</exception>
private void button1_Click(object sender, EventArgs e)
{
try
{
Operation1("One");
Operation2("Two");
Operation3("Three");
MessageBox.Show(internalValue);
}
catch (ArgumentNullException ex)
{
textBoxException.Text = ex.Message + (char) 13 + (char) 10 + ex.StackTrace;
}
catch (AppSpecificException ex)
{
//textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw;
}
catch (Exception ex)
{
textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw new AppSpecificException("crash", ex);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
button1_Click(sender, e);
}
catch (AppSpecificException ex)
{
textBoxException.Text = ex.SpecificMessage + (char) 13 + (char) 10 + ex.SpecificTrace;
}
}
Try to avoid creating a new exception and and rethrowing, since throwing an exception sets the stack trace to where the exception was thrown. Just do a plain throw. See Too Much Reuse on Eric Lippert's Blog.
I'd recommend putting more thought into what patterns you want to use for "handing"
If your handling patterns come down to log or rethrow, then the rethrown error will eventually be logged. So in the end, it's just error logging. If you're using ASP.NET use elmah so at least your code isn't covered with try/catch-and-log boiler plate.
There are only a few ways to "handle" errors that don't end in mere logging.
Re-try. (Watch out for infinite loops)
Wait and re-try.
Try different but equivalent technique (Can't connect on http? try connecting on https).
Establish the missing conditions (create the folder that threw the FolderNotFoundException)
Ignore the error-- think twice about this, it makes sense only when the error isn't really a problem, like if a 3rd party library is warning you about a condition that doesn't apply.
A good solution about exception handling is using Interception. However you must validate if this pattern can be applied to your application depending on the architecture : Interception requires a container.
The principle is to factorise your exception handling outside the methods by using attributes (custom) on them and then use the container to initialize your instances. The container will proxy theses instances by reflection : its called instances interceptors.
You'll just have to call your methods as usual via theses instances and let interception mechanism do the job you coded before or after the method.
Note that you can add try catch in the methods to manage specific exception that are unmanaged in your interceptors.
Unity interception : http://msdn.microsoft.com/en-us/library/dd140045.aspx
Related
I'm looking at the article C# - Data Transfer Object on serializable DTOs.
The article includes this piece of code:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
throw ex;
}
}
The rest of the article looks sane and reasonable (to a noob), but that try-catch-throw throws a WtfException... Isn't this exactly equivalent to not handling exceptions at all?
Ergo:
public static string SerializeDTO(DTO dto) {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
Or am I missing something fundamental about error handling in C#? It's pretty much the same as Java (minus checked exceptions), isn't it? ... That is, they both refined C++.
The Stack Overflow question The difference between re-throwing parameter-less catch and not doing anything? seems to support my contention that try-catch-throw is-a no-op.
EDIT:
Just to summarise for anyone who finds this thread in future...
DO NOT
try {
// Do stuff that might throw an exception
}
catch (Exception e) {
throw e; // This destroys the strack trace information!
}
The stack trace information can be crucial to identifying the root cause of the problem!
DO
try {
// Do stuff that might throw an exception
}
catch (SqlException e) {
// Log it
if (e.ErrorCode != NO_ROW_ERROR) { // filter out NoDataFound.
// Do special cleanup, like maybe closing the "dirty" database connection.
throw; // This preserves the stack trace
}
}
catch (IOException e) {
// Log it
throw;
}
catch (Exception e) {
// Log it
throw new DAOException("Excrement occurred", e); // wrapped & chained exceptions (just like java).
}
finally {
// Normal clean goes here (like closing open files).
}
Catch the more specific exceptions before the less specific ones (just like Java).
References:
MSDN - Exception Handling
MSDN - try-catch (C# Reference)
First, the way that the code in the article does it is evil. throw ex will reset the call stack in the exception to the point where this throw statement is losing the information about where the exception actually was created.
Second, if you just catch and re-throw like that, I see no added value. The code example above would be just as good (or, given the throw ex bit, even better) without the try-catch.
However, there are cases where you might want to catch and rethrow an exception. Logging could be one of them:
try
{
// code that may throw exceptions
}
catch(Exception ex)
{
// add error logging here
throw;
}
Don't do this,
try
{
...
}
catch(Exception ex)
{
throw ex;
}
You'll lose the stack trace information...
Either do,
try { ... }
catch { throw; }
OR
try { ... }
catch (Exception ex)
{
throw new Exception("My Custom Error Message", ex);
}
One of the reason you might want to rethrow is if you're handling different exceptions, for
e.g.
try
{
...
}
catch(SQLException sex)
{
//Do Custom Logging
//Don't throw exception - swallow it here
}
catch(OtherException oex)
{
//Do something else
throw new WrappedException("Other Exception occured");
}
catch
{
System.Diagnostics.Debug.WriteLine("Eeep! an error, not to worry, will be handled higher up the call stack");
throw; //Chuck everything else back up the stack
}
C# (before C# 6) doesn't support CIL "filtered exceptions", which VB does, so in C# 1-5 one reason for re-throwing an exception is that you don't have enough information at the time of catch() to determine whether you wanted to actually catch the exception.
For example, in VB you can do
Try
..
Catch Ex As MyException When Ex.ErrorCode = 123
..
End Try
...which would not handle MyExceptions with different ErrorCode values. In C# prior to v6, you would have to catch and re-throw the MyException if the ErrorCode was not 123:
try
{
...
}
catch(MyException ex)
{
if (ex.ErrorCode != 123) throw;
...
}
Since C# 6.0 you can filter just like with VB:
try
{
// Do stuff
}
catch (Exception e) when (e.ErrorCode == 123456) // filter
{
// Handle, other exceptions will be left alone and bubble up
}
My main reason for having code like:
try
{
//Some code
}
catch (Exception e)
{
throw;
}
is so I can have a breakpoint in the catch, that has an instantiated exception object. I do this a lot while developing/debugging. Of course, the compiler gives me a warning on all the unused e's, and ideally they should be removed before a release build.
They are nice during debugging though.
A valid reason for rethrowing exceptions can be that you want to add information to the exception, or perhaps wrap the original exception in one of your own making:
public static string SerializeDTO(DTO dto) {
try {
XmlSerializer xmlSer = new XmlSerializer(dto.GetType());
StringWriter sWriter = new StringWriter();
xmlSer.Serialize(sWriter, dto);
return sWriter.ToString();
}
catch(Exception ex) {
string message =
String.Format("Something went wrong serializing DTO {0}", DTO);
throw new MyLibraryException(message, ex);
}
}
Isn't this exactly equivalent to not
handling exceptions at all?
Not exactly, it isn't the same. It resets the exception's stacktrace.
Though I agree that this probably is a mistake, and thus an example of bad code.
You don't want to throw ex - as this will lose the call stack. See Exception Handling (MSDN).
And yes, the try...catch is doing nothing useful (apart from lose the call stack - so it's actually worse - unless for some reason you didn't want to expose this information).
This can be useful when your programming functions for a library or dll.
This rethrow structure can be used to purposefully reset the call stack so that instead of seeing the exception thrown from an individual function inside the function, you get the exception from the function itself.
I think this is just used so that the thrown exceptions are cleaner and don't go into the "roots" of the library.
A point that people haven't mentioned is that while .NET languages don't really make a proper distinction, the question of whether one should take action when an exception occurs, and whether one will resolve it, are actually distinct questions. There are many cases where one should take action based upon exceptions one has no hope of resolving, and there are some cases where all that is necessary to "resolve" an exception is to unwind the stack to a certain point--no further action required.
Because of the common wisdom that one should only "catch" things one can "handle", a lot of code which should take action when exceptions occur, doesn't. For example, a lot of code will acquire a lock, put the guarded object "temporarily" into a state which violates its invariants, then put it object into a legitimate state, and then release the lock back before anyone else can see the object. If an exception occurs while the object is in a dangerously-invalid state, common practice is to release the lock with the object still in that state. A much better pattern would be to have an exception that occurs while the object is in a "dangerous" condition expressly invalidate the lock so any future attempt to acquire it will immediately fail. Consistent use of such a pattern would greatly improve the safety of so-called "Pokemon" exception handling, which IMHO gets a bad reputation primarily because of code which allows exceptions to percolate up without taking appropriate action first.
In most .NET languages, the only way for code to take action based upon an exception is to catch it (even though it knows it's not going to resolve the exception), perform the action in question and then re-throw). Another possible approach if code doesn't care about what exception is thrown is to use an ok flag with a try/finally block; set the ok flag to false before the block, and to true before the block exits, and before any return that's within the block. Then, within finally, assume that if ok isn't set, an exception must have occurred. Such an approach is semantically better than a catch/throw, but is ugly and is less maintainable than it should be.
While many of the other answers provide good examples of why you might want to catch an rethrow an exception, no one seems to have mentioned a 'finally' scenario.
An example of this is where you have a method in which you set the cursor (for example to a wait cursor), the method has several exit points (e.g. if () return;) and you want to ensure the cursor is reset at the end of the method.
To do this you can wrap all of the code in a try/catch/finally. In the finally set the cursor back to the right cursor. So that you don't bury any valid exceptions, rethrow it in the catch.
try
{
Cursor.Current = Cursors.WaitCursor;
// Test something
if (testResult) return;
// Do something else
}
catch
{
throw;
}
finally
{
Cursor.Current = Cursors.Default;
}
One possible reason to catch-throw is to disable any exception filters deeper up the stack from filtering down (random old link). But of course, if that was the intention, there would be a comment there saying so.
It depends what you are doing in the catch block, and if you are wanting to pass the error on to the calling code or not.
You might say Catch io.FileNotFoundExeption ex and then use an alternative file path or some such, but still throw the error on.
Also doing Throw instead of Throw Ex allows you to keep the full stack trace. Throw ex restarts the stack trace from the throw statement (I hope that makes sense).
In the example in the code you have posted there is, in fact, no point in catching the exception as there is nothing done on the catch it is just re-thown, in fact it does more harm than good as the call stack is lost.
You would, however catch an exception to do some logic (for example closing sql connection of file lock, or just some logging) in the event of an exception the throw it back to the calling code to deal with. This would be more common in a business layer than front end code as you may want the coder implementing your business layer to handle the exception.
To re-iterate though the There is NO point in catching the exception in the example you posted. DON'T do it like that!
Sorry, but many examples as "improved design" still smell horribly or can be extremely misleading. Having try { } catch { log; throw } is just utterly pointless. Exception logging should be done in central place inside the application. exceptions bubble up the stacktrace anyway, why not log them somewhere up and close to the borders of the system?
Caution should be used when you serialize your context (i.e. DTO in one given example) just into the log message. It can easily contain sensitive information one might not want to reach the hands of all the people who can access the log files. And if you don't add any new information to the exception, I really don't see the point of exception wrapping. Good old Java has some point for that, it requires caller to know what kind of exceptions one should expect then calling the code. Since you don't have this in .NET, wrapping doesn't do any good on at least 80% of the cases I've seen.
In addition to what the others have said, see my answer to a related question which shows that catching and rethrowing is not a no-op (it's in VB, but some of the code could be C# invoked from VB).
Most of answers talking about scenario catch-log-rethrow.
Instead of writing it in your code consider to use AOP, in particular Postsharp.Diagnostic.Toolkit with OnExceptionOptions IncludeParameterValue and
IncludeThisArgument
Rethrowing exceptions via throw is useful when you don't have a particular code to handle current exceptions, or in cases when you have a logic to handle specific error cases but want to skip all others.
Example:
string numberText = "";
try
{
Console.Write("Enter an integer: ");
numberText = Console.ReadLine();
var result = int.Parse(numberText);
Console.WriteLine("You entered {0}", result);
}
catch (FormatException)
{
if (numberText.ToLowerInvariant() == "nothing")
{
Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}
else
{
throw;
}
}
finally
{
Console.WriteLine("Freed some resources.");
}
Console.ReadKey();
However, there is also another way of doing this, using conditional clauses in catch blocks:
string numberText = "";
try
{
Console.Write("Enter an integer: ");
numberText = Console.ReadLine();
var result = int.Parse(numberText);
Console.WriteLine("You entered {0}", result);
}
catch (FormatException) when (numberText.ToLowerInvariant() == "nothing")
{
Console.WriteLine("Please, please don't be lazy and enter a valid number next time.");
}
finally
{
Console.WriteLine("Freed some resources.");
}
Console.ReadKey();
This mechanism is more efficient than re-throwing an exception because
of the .NET runtime doesn’t have to rebuild the exception object
before re-throwing it.
using (SqlConnection con = new SqlConnection())
{
try
{
con.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This works fine. But I want to know can we handle exception without using try catch like some thing if else? Or is it mendetory to use try catch.
There is no other mechanism to handle an exception other than try catch. It sounds like you want something like
if(connection.DidAnErrorOccur)
but that doesn't exist.
ok, you can implementing de Application_Error in the global.asax, this method is the first line of defense for the errors and is for all the application
http://msdn.microsoft.com/en-us/library/24395wz3%28v=vs.100%29.aspx
for specific page for example default.aspx, you can implementing Page_Error
http://msdn.microsoft.com/en-us/library/ed577840%28v=vs.100%29.aspx
if you are working in mvc so you can implementing the OnException(ExceptionContext filterContext) in every controller that you want, this method is called when an unhandled exception occurs.
http://devproconnections.com/aspnet-mvc/aspnet-mvc-tutorial-handling-errors-and-exceptions
or you can implementing your error atribute
https://www.simple-talk.com/dotnet/asp.net/handling-errors-effectively-in-asp.net-mvc/
For another hand maybe you can use the Assert statement, with this you can evaluate a condition
http://msdn.microsoft.com/en-us/library/ttcc4x86.aspx
Only way is to check for all the conditions that would return an error. You should be doing this anyway. Try/catch is expensive. Try catch should be a last resort and there is no way around it for that purpose.
The best alternative I can give you is Elmah. http://code.google.com/p/elmah/
It will handle all your uncaught errors and log them. From there I would suggest fixing said errors or catching the specific errors you expect and not just catch any error that might occur. This is best to do so you can fix potential problems and not simply skip over code because an exception occurred.
Tejs' answer is correct, I believe there is no other mechanism to handle errors.
You can, however, handle more specific errors. You can also declare variables outside the try catch to see if it succeeded.
Example:
using (SqlConnection con = new SqlConnection())
{
bool sqlErrorOccurred;
try
{
con.Open();
sqlErrorOccurred = false;
}
catch (SqlException ex)
{
sqlErrorOccurred = true;
}
if(sqlErrorOccurred)
{
MessageBox.Show("A Sql Exception Occurred");
}
}
The answers above are correct. However, one additional thing to note is that it is possible to set up a global exception handler. This doesn't solve the need for defensive coding as previously mentioned. However, if there are concerns that all exceptions need to be handled (for example, to log the error), then this approach can be very helpful.
I'm building a system that uses real-time streaming data, and needs, therefore, to handle errors that could occur when everything else is pretty much idle. The API I'm using passes the errors back through to the program though a method named "error", with the exception attached. This method could then throw the error, but that is problematic, because I can't see how putting my whole program entirely within a try-catch block is a good idea.
So, to get around it, I'll set up an event handler to fire the event in the main part of my program, which can then deal with whatever error gets thrown at that point in time.
For example:
In the main class:
private void Error(object sender, EventArgs e) {
Exception ex = sender as Exception;
Console.WriteLine("Error: " + ex); // Or whatever you want to do with the exception
// You could even add this if you want to then use the try -catch sequence (which
// makes the exception easier to parse and also enables you to stop the program
// with unhandled exceptions if it's something catastrophic:
try {
throw ex;
} catch (put.your.exception.detail.here) {
// do stuff
} finally {
// do other stuff
}
}
(In the class that receives the error from the API):
class Foo {
public event EventHandler ThrowError;
protected virtual void OnError(Object src, EventArgs e) {
if (ThrowError != null) {
ThrowError(src, e);
}
}
private virtual void error(Exception e) {
OnError(e, EventArgs.Empty);
}
}
In .NET core 3.1 (or before?), You could set up a global catcher for unhandled exceptions. However, the APP won't continue to run after that.
Here is an example:
https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netcore-3.1
I have a webservice that returns xml.The problem is methods that are executed "deep" in code where a simple return won't stop program execution.
What happens is I set my xml error message in a catch statement but the code will keep executing through the rest of the outer method and overwrite my xml error response.
Is there a design pattern or best practice to get around this?
Main Program Block SomeClass
execute someMethod() ----> public someMethod()
{
-----> private method()// try / catch error occurred (send back an xml error response)
// code execution continues and does some stuff and generates an xml response
<request>
<success>true</success>
</request>
}
catch (Exception)
{
// Set errors here
throw;
}
This will rethrow the exception. Is that what you're looking for?
You can re-throw the exception. For example:
private static string errorMessage;
static void Main(string[] args)
{
try
{
Test1();
}
catch (Exception ex)
{
Console.WriteLine("Something went wrong deep in the bowels of this application! " + errorMessage );
}
}
static void Test1()
{
try
{
Test2(1);
Test2(0);
}
catch (Exception ex)
{
errorMessage = ex.Message;
throw;
}
}
static string Test2(int x)
{
if (x==0) throw new ArgumentException("X is 0!");
return x.ToString();
}
An additional piece of advice: When re-throwing an exception, use throw;, not throw ex;, in order to preserve the stack trace. See this for some more information on the subject.
You need to consider setting up Exception boundaries within your architecture.
I've used Microsoft's Exception Handling Block successfully in the past to do this.
This will allow you to set up different policies for dealing with and propagating exceptions as shown in the diagram below;
It will help you deal with scenarios such as;
Logging
Replacing
Wrapping
Propagating
User friendly messages
It's worth a look depending on how far you want to take your exception handling.
It's generally wise to catch your exceptions as far up the chain as possible. So it would be the main service method's responsibility to catch different types of exceptions and determine the appropriate response. Deep-down code should not just "swallow" the exception unless it really knows how to handle it and move on gracefully.
If you want to make it so certain exceptions can tell the upper-level code that it's supposed to use specific information for the response, you can create a custom exception type with properties that the exception-catching code in the service method can check.
// In your deep down code
catch (Exception e)
{
throw new ReturnErrorMessageException("The user should see this message.", e);
}
// In your service method
catch (SendErrorMessageException e)
{
Response.Message = e.UserFacingErrorMessage;
_logger.LogError("An error occurred in the web service...", e);
}
Probably the best solution for what you are looking for is to use Aspect Oriented Programming (AOP) and create an Exception handling Aspect(s) that catches and handles all the exceptions then you check for exceptions at the service level.
The advantage of this is it removes the try catch from your code and enables you to handle the exceptions in the a modular manner.
Some AOP solutions for .NET include Castle Windsor, Spring.NET and Microsoft Unity.
I'm refactoring a medium-sized WinForms application written by other developers and almost every method of every class is surrounded by a try-catch block. 99% of the time these catch blocks only log exceptions or cleanup resources and return error status.
I think it is obvious that this application lacks proper exception-handling mechanism and I'm planning to remove most try-catch blocks.
Is there any downside of doing so? How would you do this? I'm planning to:
To log exceptions appropriately and prevent them from propagating to the user, have an Application.ThreadException handler
For cases where there's a resource that needs cleanup, leave the try-catch block as it is
Update: Using using or try-finally blocks is a better way. Thanks for the responses.
In methods that "return-false-on-error", let the exception propagate and catch it in the caller instead
Any corrections/suggestions are welcome.
Edit: In the 3rd item, with "return-false-on-error" I meant methods like this:
bool MethodThatDoesSomething() {
try {
DoSomething(); // might throw IOException
} catch(Exception e) {
return false;
}
}
I'd like to rewrite this as:
void MethodThatDoesSomething() {
DoSomething(); // might throw IOException
}
// try-catch in the caller instead of checking MethodThatDoesSomething's return value
try {
MethodThatDoesSomething()
} catch(IOException e) {
HandleException(e);
}
"To log exceptions appropriately and prevent them from propagating to the user, have an Application.ThreadException handler"
Would you then be able to tell the user what happened? Would all exceptions end up there?
"For cases where there's a resource that needs cleanup, leave the try-catch block as it is"
You can use try-finally blocks as well if you wish to let the exception be handled elsewhere. Also consider using the using keyword on IDisposable resources.
"In methods that "return-false-on-error", let the exception propagate and catch it in the caller instead"
It depends on the method. Exceptions should occur only in exceptional situations. A FileNotFoundException is just weird for the FileExists() method to throw, but perfectly legal to be thrown by OpenFile().
For cleanup rather use try-finally or implement the IDisposable as suggested by Amittai. For methods that return bool on error rather try and return false if the condition is not met. Example.
bool ReturnFalseExample() {
try {
if (1 == 2) thow new InvalidArgumentException("1");
}catch(Exception e) {
//Log exception
return false;
}
Rather change to this.
bool ReturnFalseExample() {
if (1 == 2) {
//Log 1 != 2
return false;
}
If i'm not mistaken try catches are an expensive process and when possible you should try determine if condition is not met rather then just catching exceptions.
}
As an option for "return-false-on-error" you can clean up the code this way:
static class ErrorsHelper {
public static bool ErrorToBool(Action action) {
try {
action();
return true;
} catch (Exception ex) {
LogException(ex);
return false;
}
}
private static void LogException(Exception ex) {
throw new NotImplementedException();
}
}
and usage example:
static void Main(string[] args) {
if (!ErrorToBool(Method)) {
Console.WriteLine("failed");
} else if (!ErrorToBool(() => Method2(2))) {
Console.WriteLine("failed");
}
}
static void Method() {}
static void Method2(int agr) {}
The best is as said by others, do exception handling at 1 place. Its bad practice to conceal the raised exception rather than allowing to bubble up.
You should only handle only the exceptions that you are expecting, know how to handle and they are not corrupt the state of your application, otherwise let them throw.
A good approach to follow is to log the exception first, then Restart your application, just like what Microsoft did when office or visual studio crashing. To do so you have to handle the application domain unhanded exception, so:
AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainUnhandledException;
//Add these two lines if you are using winforms
Application.ThreadException += OnApplicationThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
private void OnCurrentDomainUnhandledException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
//Log error
//RestartTheApplication
}
Here an example on how to restart your application.
I think your strategy of removing try/catch block which just appear to do generic thoughtless logging is fine. Obviously leaving the cleanup code is necessary. However, I think more clarification is needed for your third point.
Return false on error methods are usually OK for things where exceptions are unavoidable, like a file operation in your example. Whereas I can see the benefit of removing exception handling code where it's just been put in thoughtlessly, I would consider carefully what benefit you get by pushing responsibility for handling an exception of this kind higher up in the call chain.
If the method is doing something very specific (it's not generic framework code), and you know which callers are using it, then I'd let it swallow the exception, leaving the callers free of exception handling duties. However, if it's something more generic and maybe more of a framework method, where you're not sure what code will be calling the method, I'd maybe let the exception propagate.
You may try to use AOP.
In AOP through PostSharp, for example, you can handle exceptions in one central place (piece of code) as an aspect.
Look at the examples in documentation to have an idea => Docs on Exception Handling with PostSharp.
we can remove try and catch by adding condition Like
string emailAddresses = #"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$";
if (!Regex.IsMatch(Email, emailAddresses))
{
throw new UserFriendlyException($"E-mail Address Is not Valid");
}**strong text**
Suppose I have the following two classes in two different assemblies:
//in assembly A
public class TypeA {
// Constructor omitted
public void MethodA
{
try {
//do something
}
catch {
throw;
}
}
}
//in assembly B
public class TypeB {
public void MethodB
{
try {
TypeA a = new TypeA();
a.MethodA();
}
catch (Exception e)
//Handle exception
}
}
}
In this case, the try-catch in MethodA just elevates the exception but doesn't really handle it. Is there any advantage in using try-catch at all in MethodA? In other words, is there a difference between this kind of try-catch block and not using one at all?
In your example, there is no advantage to this. But there are cases where it is desirable to just bubble up a specific exception.
public void Foo()
{
try
{
// Some service adapter code
// A call to the service
}
catch (ServiceBoundaryException)
{
throw;
}
catch (Exception ex)
{
throw new AdapterBoundaryException("some message", ex);
}
}
This allows you to easily identify which boundary an exception occurred in. In this case, you would need to ensure your boundary exceptions are only thrown for code specific to the boundary.
Yes there is a difference. When you catch an exception, .NET assumes you are going to handle it in some way, the stack is unwound up to the function that is doing the catch.
If you don't catch it will end up as an unhandled exception, which will invoke some kind of diagnostic (like a debugger or a exception logger), the full stack and its state at the actual point of failure will be available for inspection.
So if you catch then re-throw an exception that isn't handled elsewhere you rob the diagnostic tool of the really useful info about what actually happened.
With the code the way you've written it for MethodA, there is no difference. All it will do is eat up processor cycles. However there can be an advantage to writing code this way if there is a resource you must free. For example
Resource r = GetSomeResource();
try {
// Do Something
} catch {
FreeSomeResource();
throw;
}
FreeSomeResource();
However there is no real point in doing it this way. It would be much better to just use a finally block instead.
Just rethrowing makes no sense - it's the same as if you did not do anything.
However it gets useful when you actually do something - most common thing is to log the exception. You can also change state of your class, whatever.
Taken as-is, the first option would seem like a bad (or should that be 'useless'?) idea. However, it is rarely done this way. Exceptions are re-thrown from within a Catch block usually under two conditions :
a. You want to check the exception generated for data and conditionally bubble it up the stack.
try
{
//do something
}
catch (Exception ex)
{
//Check ex for certain conditions.
if (ex.Message = "Something bad")
throw ex;
else
//Handle the exception here itself.
}
b. An unacceptable condition has occurred within a component and this information needs to be communicated to the calling code (usually by appending some other useful information or wrapping it in another exception type altogether).
try
{
//do something
}
catch (StackOverflowException ex)
{
//Bubble up the exception to calling code
//by wrapping it up in a custom exception.
throw new MyEuphemisticException(ex, "Something not-so-good just happened!");
}
Never do option A. As Anton says, it eats up the stack trace. JaredPar's example also eats up the stacktrace. A better solution would be:
SomeType* pValue = GetValue();
try {
// Do Something
} finally {
delete pValue;
}
If you got something in C# that needs to be released, for instance a FileStream you got the following two choices:
FileStream stream;
try
{
stream = new FileStream("C:\\afile.txt");
// do something with the stream
}
finally
{
// Will always close the stream, even if there are an exception
stream.Close();
}
Or more cleanly:
using (FileStream stream = new FileStream("c:\\afile.txt"))
{
// do something with the stream
}
Using statement will Dispose (and close) the stream when done or when an exception is closed.
When you catch and throw, it allows you to set a breakpoint on the throw line.
Re-throwing exceptions can be used to encapsulate it into generic exception like... consider following example.
public class XmlException: Exception{
....
}
public class XmlParser{
public void Parse()
{
try{
....
}
catch(IOException ex)
{
throw new XmlException("IO Error while Parsing", ex );
}
}
}
This gives benefit over categorizing exceptions. This is how aspx file handlers and many other system code does exception encapsulation which determines their way up to the stack and their flow of logic.
The assembly A - try catch - block does not make any sense to me. I believe that if you are not going to handle the exception, then why are you catching those exceptions.. It would be anyway thrown to the next level.
But, if you are creating a middle layer API or something like that and handling an exception ( and hence eating up the exception) in that layer does not make sense, then you can throw your own layer ApplicationException. But certainly rethrowing the same exception does not make sense.
Since the classes are in 2 different assemblies, you may want o simply catch the exception for logging it and then throw it back out to the caller, so that it can handle it the way it sees fit. A throw instead of a throw ex will preserve contextual information about where the exception originated. This can prove useful when your assembly is an API/framework where in you should never swallow exceptions unless its meaningful to do so but helpful nonetheless in trouble shooting if it's logged for example to the EventLog.
You can use try{} catch(ex){} block in Method A only if you could catch the specific exception which can be handled in MethodA() (for eg: logging ).
Another option is chain the exception using the InnerException property and pass it to the caller. This idea will not kill the stack trace.