I've got some UI code that looks like this:
try
{
SomeClass classInstance = new SomeClass(someId);
}
catch (Exception exception)
{
// Content wasn't created, show a message, stop processing
return;
}
It seems the try catch was added because the constructor for SomeClass would bomb out if the someId it receives isn't valid, and data couldn't be found in a DB.
Running this code through FXCop recently, it warns against using the general Exception, but all SomeClass does is throw a new Exception with a message to say it failed to initialize.
I guess the problem is that the class constructor should have it's own custom exception, which I could then handle in my UI, but I wonder what else I could do to the code above to handle the exception, that meets FXCop requirements?
FxCop's rule exists because the catch (Exception) block above catches all possible exceptions, including low-level exceptions like StackOverflowException that you probably can't catch in a useful way.
The right approach is definitely to throw a more specific type: either one you've invented, or an existing .NET framework exception type that closely matches your situation. (When in doubt, I normally go for InvalidOperationException.)
Alternatively, you could check the exact exception type when catching it. This won't prevent the FxCop warning, but it should address the underlying problem:
catch (Exception exception)
{
if (exception.GetType() == typeof(Exception))
{
// Content wasn't created, show a message, stop processing
return;
}
else
{
// Some other exception type that wasn't thrown from our code -
// delegate to a higher-level exception handler
throw;
}
}
You don't need a custom exception; just use one of the dozens that already exist in the framework for given circumstances. If someId is bad, throw an ArgumentException -- that's what it's made for. If something's null that shouldn't be, a NullReferenceException will occur; just let it be thrown. Etc. Throwing a plain Exception is a bit like saying "something went wrong -- read the message for details" rather than "this went wrong".
FxCop is complaining about catch (Exception) because it's too commonly abused to swallow up all exceptions rather than letting them propagate and be handled by code that knows how to do so. You should be able to say what types of exceptions are being thrown and catch those, while letting those you don't recognize make their way up the call stack.
You should fix the class constructor. Throwing Exception is never a good idea.
However, to work around the issue you have temporarily (as this is a horrible, unreliable hack), you could check the message of the exception against the one you're expecting:
catch (Exception exception)
{
if (exception.Message == "whatever your class sets the message to")
// Content wasn't created, show a message, stop processing
return;
else
// Any other exception should bubble
throw;
}
Using InvalidOperationException in place of throwing Exception sounds like it might be sensible.
If FXCop doesn't like handling the general Exception (and I tend to agree) then maybe you have access to SomeClass's source code. Modify the constructor to throw an exception that is more specific, e.g. ArgumentOutOfRangeException or some custom exception.
In that case your code would then look as follows:
try
{
SomeClass classInstance = new SomeClass(someId);
}
catch(ArgumentOutOfRangeException exception)
{
// Content wasn't created, show a message, stop processing
return;
}
As many others have said, the constructor should not be throwing a naked Exception. Seeing that the constructor retrieves data from DB and throws based on the result, the best solution is to create your own exception class.
Creating exceptions is super-easy in Visual studio. Just type in Exception and press TAB. It will then create the exception class with required constructors(all four of them). Do not be afraid to create classes that don't do very much, that's what they are designed for.
This is how I would write this class:
public class SomeClass {
public SomeClass(int someId) {
if (someId < 0) //validation on the ID, can it be negative?
throw new ArgumentException("someId", "ID cannot be negative");
//Perform DB operation
if (/*DB error - not found*/)
throw new DataNotFoundException("Cannot find record with ID " + someId);
}
}
[Serializable]
public class DataNotFoundException : Exception {
public DataNotFoundException() { }
public DataNotFoundException(string message) : base(message) { }
public DataNotFoundException(string message, Exception inner) : base(message, inner) { }
protected DataNotFoundException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
Related
I have followed this way of handling exception in my application. But my lead said I am doing it wrong. I am simply wrapping and rethrowing the same exception, which will impact performance.
What is wrong with my approach? Does anyone have any suggestions on how I can log and handle the exception here?
public class BusinessRepository : IBusinessRepo
{
public List<Employee> GetEmployees()
{
try
{
//do some DB operations
}
catch (SQLException sqlex)
{
Logger.Log("Exception detail with full stack trace");
throw new DALException(sqlex, "Error in data access layer");
}
}
}
public class BusinessLayerClass : IBusinessLayer
{
private readonly IBusinessRepo Repo;
public BusinessLayerClass(IBusinessRepo rep)
{
Repo = rep;
}
public List<Employee> GetEmployees()
{
try
{
List<Employee> emps= return Repo.GetEmployees();
}
catch (DALException dex)
{
//do nothin as it got already logged
throw;
}
catch (Exception ex)
{
Logger.Log(ex, "Business layer ex");
throw new BusinessLayerEx(ex);
}
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
try
{
List < Employee >= BusinessLayerClass.GetEmployees();
}
catch (DALException)
{
//show error msg to user
}
catch (BusinessLayerEx)
{
//show error msg to user
}
catch (Exception ex)
{
Logger.Log();
//show error msg to user
}
return View(emps);
}
}
Do i follow right way of bubbling and handling and logging shown above?
I'm inclined to agree with your way of doing this, as long as two conditions are met:
Your Logger.Log statements log something more meaningful/useful than what you've indicated here (I'm guessing your code here is just a sample message indicating the error is logged). If it provides information you can use to track down the cause of the exception, good.
Your //show error msg to user comments mean that in that location, you render a nice view explaining that an error has occured, and you aren't just showing a default exception screen/strack trace.
As far as your throw; when you catch the DALException you just threw: that's fine. Your goal here seems to be to catch any exception coming out of the previous layer and log it, throwing your own exception afterwards. Since DALException will only be thrown if you've already logged another error and thrown it yourself, it's perfectly fine to let it bubble up past this level.
The general rule of thumb for exceptions is do not catch them unless you can "do something about it", i.e. add value. Ideally this would be some kind of graceful recovery to the point that the user never knows there was a hiccup, but at the very minimum this would include logging the exception -- which you are doing.
Do not catch an exception only to immediately re-throw it. That adds no value. (An exception to this might be if you need to change the type of exception to something more informative/appropriate to the context).
Throwing and catching exceptions is expensive compared to any normal return mechanism, but it's kind of besides the point - we're not supposed to use exceptions as normal control-flow mechanisms, but to handle exceptional things.
Exception handling can be quite challenging technically. After all, most of the time we exactly don't expect them. But what can make it near-impossible to get exception handling "right" is when the team or project simply doesn't have any kind of strategy for error handling. In an ideal world, we would know at the outset exactly what sort of error conditions we need to cope with, and we'd design the whole application with those in mind (along with the gazillion other constraints we also need to keep in mind, from code readability to performance).
I'd say if your lead says "this is wrong" then it's fair to ask "what's our error-handling strategy?". If you don't even know what purpose your code is supposed to fulfill, how can you possibly deliver great code?
There's nothing wrong with your approach but I don't see that your custom exceptions add much value. A example of how wrapping an exception in the DAL could add value is if you wrapped specific SQL exceptions, such as unique key violation, in a custom exception so that your UI could present a meaningful error message.
As for performance, it doesn't really matter anyway because something very bad has already happened.
I try to put a exception logic which a part of a system can fall back to on unexpected behaviors.
The work should be done of a new class that inherits Exception object and extend the functionality with a new "exit" which consist of a error-signal to the user and a logging routine.
I may need to understand the use of throw better, but I though I could make it fairly transparent by i.e. this:
public SomeObject GetVersion(byte p)
{
switch ((SomeObject)p)
{
case Version.SomeType1:
...
break;
case Version.SomeType2:
...
break;
default:
throw new UnexpectedQueryException(this.someOtherObject, errorCode);
}
return (SomeObject)p;
}
I think you can see what I'm trying to do here.
I try to throw when the application can't serve the request. The throw are meant to put the execution through the exception (which generates a adequate error code to caller). This example is a error of type "I know you gived me a 9 but only 1-8 is allowed here)", which errorCode sends further to the UnexpectedQueryException(...).
Unfortunately the application take the throw as unhandled and closes my Thread and application won't operate until restart. Beside this scenario i'm also use this throw in catch statements.
In my eyes, this is Very handled.
What best practice here?
I want the exception handling to be a "fall back" to activate on different scenarios (like above) so I always have an easy way to communicate an error back to the user (which mean I can send very exact info about where the exception is).
Also i, Of Course, want the application to continue working.
A part of code from the Exception logic,
public class UnexpectedQueryException: CommunicationException
{
public UnexpectedQueryException(SomeObject object, ErrorCode errorCode) : base("UnexpectedQueryException", object, errorCode)
{
.........
}
}
Which, in turn, inherits the base Exception object,
public class CommunicationException : Exception
{
..some fields..
public CommunicationException(string Message, SomeObject object, ErrorCode errorcode)
{
.....
}
public CommunicationException() : base("CommunicationException")
{ }
}
If you throw an exception in your code, you need to catch it and do something with it - if you don't, you have not handled it.
If you throw within a catch block, the same thing applies. You have thrown an exception which will keep propagating till a suitable catch block has been found. If non exists, it is unhandled.
You need to structure your higher level (UI) code so it catches the right types of exceptions and communicates the information you want back to the user:
try
{
// code that can throw
}
catch(VerySpecificException ex)
{
// communicate to user details about VerySpecificException.
// possibly log.
// Do not re-throw or throw a new excpetion as it is now handled.
}
catch(AnotherSpecificException ex)
{
// communicate to user details about AnotherSpecificException.
}
catch(LessSpecificException ex)
{
// communicate to user details about LessSpecificException.
}
catch(EveLessSpecificException ex)
{
// communicate to user details about EvenLessSpecificException.
}
You need to understand how and when to catch exceptions.
The nasty thing with throwing exceptions in (worker) threads is that any top-level exception handler (such as a try/catch in program.cs) will not catch and log the exceptions thrown in threads. Hence you should always have a general try/catch in the thread entry method, at least if you do not want your application to die.
A pretty simply rule is that you should only catch exceptions that you can handle to deliver the expected result from a method. And at entry point to prevent the application from dying (but sometimes it's better to let the application die).
To understand exceptions better, you might want to read my blog articles about exceptions: http://blog.gauffin.org/tag/exceptions/
A throw does not handle an error but it raises one. Without a throw there is no error to handle.
You handle an exception by catching it. You need a try - catch block somewhere in your code which calls GetVersion (or somewhere in the code which calls the code that calls GetVersion etc.). If you don't catch the UnexpectedQueryException in your call hierarchy, it is unhandled and your application will stop.
An example which calls GetVersion different times (without handling exceptions).
List<SomeObject> GetAllVersions(byte[] bytes)
{
var result = new List<SomeObject>();
foreach (byte b in bytes)
{
result.Add(GetVersion(b));
}
return result;
}
Now it's up to you where to handle the exception. You could do it inside the loop, so that you get a result, containing all the successfully retrieved objects:
foreach (byte b in bytes)
{
try
{
result.Add(GetVersion(b));
}
catch (UnexpectedQueryException e)
{
// this is where your exception handling starts
// display an error, log the exception, ...
}
}
Or you can handle the exception at another level of your application, e.g. wrap the call to GetAllVersions into a try-catch block:
List<SomeObject> = null;
try
{
versionList = GetAllVersions(bytes)
// do something with versionList
}
catch (UnexpectedQueryException e)
{
// this is where your exception handling starts
// display an error, log the exception, ...
// Note that versionList will be null in error case
}
This is the main advantage of exceptions. They propagate throughout the call stack. So you don't need to handle it in the line of code after the error, but somewhere in your application where you think it's appropriate.
Unfortunately the application take the throw as unhandled and closes
my Thread and application won't operate until restart. Beside this
scenario i'm also use this throw in catch statements.
The code you provided will raise an exception always, because you trying to convert a value type of type byte to the reference type of type SomeObj:
public SomeObject GetVersion(byte p)
{
switch ((SomeObject)p)
{
case Version.SomeType1:
...
break;
case Version.SomeType2:
...
break;
default:
throw new UnexpectedQueryException(this.someOtherObject, errorCode);
}
return (SomeObject)p;
}
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.
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
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.