throw new Exception in a test - c#

While browsing the code of my application I faced this:
private string[] ReadFromFile(string path)
{
string[] data = null;
try
{
data = File.ReadAllLines(path);
}
catch (Exception)
{
throw new Exception("The file is not correct");
}
return data;
}
Ok so I know this code is not good and I was about to refactor this. However, this code is used in the definition of some tests for FitNesse. This code is never used in production. The parameter given in this method is supposed to be always correct. So I feel like removing the whole try/catch block and let it crash if it should. FitNesse would give us the whole details about the exception thrown, but since it's a test fixture I'm wondering if it may be ok.
File.ReadAllLines can throw a dozen of different exceptions.
So my question: Is it acceptable to have such kind of code, outside production, even if used to test production code, and in a environment under control? Or is it bad under any circumstances?

It is even worse to have such code in unit tests than having it in production code. In production code sometimes it might make a sense to hide some exception details (though they still should be delivered via InnerException for example) but in unit tests you should always see as much as possible because they are done for you (developer, not end user). So I think this entire try/catch block should be removed.
Also if in some other case you would like to fail test then I would recommend using Assert.Fail("message") construction since it makes it more clear then tests should be treated as failed if it reached this point. Not sure whether it can be applied to FitNesse though.

I would catch it, and then throw a streamlined exception that will leverage the functionality of FitNesse
private string[] ReadFromFile(string path)
{
string[] data = null;
try
{
data = File.ReadAllLines(path);
}
catch (Exception)
{
throw new Exception("message:<<Problem reading in file: " +e.getMessage() + ">>");
}
return data;
}
If you do this, the error message will appear in context and be easier to identify. Unfortunately, an unwrapped exception will appear in a exception block separate from the fixture that had the problem. The e.printStackTrace() will give you information on the output page that can give you more details.
I agree with others that in unit test code you want the exception to occur in context of the code. However your audience is different when in a unit test. The people working with it should always be developers. In the case of FitNesse tests, you are working with BAs and Testers, who may benefit from a little extra diagnostics.
The code I added is Java, and I know this is a c# test, but the spirit is the same and the "message:<< exception" should work the same in FitSharp for slim. I work in Java and ruby, so my c# is really weak.

If you catch exception you should do something with it, write logs e.g. If you only throw your own exception you lose stack trace of a last exception.

Related

Handling of exceptions, do I have to catch each specific exception?

Just a thing I've been thinking of for a while. Do I need to handle KeyNotFoundException by catching that specific exception or can I just use a "blank" catch like this:
try
{
//Code goes here
}
catch
{
}
Or do I have to do it like this:
try
{
//Code goes here
}
catch(Exception ex)
{
}
Or do I have to do it like this:
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
The reason why I ask is that when I look at crash count at App Hub I have a lot of crashes related to "KeyNotFoundException" but I never experience any crashes in my app. Could this be the problem, that I don't catch the specific exception and that App Hub crash statistics classifies it as a crash even if the exception is handled?
EDIT:
Here are some screenshots of the App Hub crash statistics (Stack Trace). Does anyone know ehat in detail it means? It has to do with my background agent and that might be the reason for why I never experience any crashes in my app:
No, the marketplace is counting only unhandled exceptions, so your app does crash.
An empty catch or catching Exceptions are the most general catches (Every exception is derived from the Exception base class, so you're catching everything.), the critical code is somewhere you don't use try-catch. Based on the exception you should check your dictionaries and think about what are the conditions which can cause error.
Generally a good practice is to check the correctness of parameters in your public methods so if any problem occurs you can provide yourself more helpful error messages, for example:
public User GetUser(string username)
{
if (String.IsNullOrEmpty(username))
throw ArgumentNullException("username");
return this.users[username];
}
In this case if things goes wrong you will see that you used a null for username, otherwise you would see a KeyNotFoundException. Hope this helps, good luck!
You can use a base exception to catch a more derived exception, so Exception will catch KeyNotFoundException because the latter inherits the former. So strictly speaking, if you want to catch "any" exception, catch (Exception) will suffice.
However, you should only catch exceptions if you can handle them in some meaningful manner. Though I'm not sure how this mindset stacks up against WP development.
As for your underlying problem, I've no idea. Does the App Hub not provide any details around the crash such as stack traces?
Your best bet is to leave the template code in place that registers for the unhandled exceptions event and put some logging into your application to record as much detail as you can about the state of the app during the crash.
No, you do not have to catch each specific exception type in a try / catch block, see the C# language reference.
However, rather than wrapping all your code in try / catch blocks, you probably want to add exception handling logic and logging into a handler for the Application.UnhandledException event. See this excellent blog post for an example of how to handle this event.
If you are interested in a specific exception, such as KeyNotFoundException in a particular part of the code then you catch it like this
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
If you want to catch a specific exception and some undefined one you do something like this
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
catch(Exception ex)
{
}
If you want to make sure your application doesn't crash use Collin's example with the Application.UnhandledException event.
You can catch all exceptions by catching the base class, but whether you want to depends on what your trying to achieve.
Generally speaking, you should only catch an exception at a level at which you have the knowledge to decide what should be done about the error, ie roll back some action, or display a message to the user. It is often the case that at a certain level it makes sense to catch a specific exception type, as that level of code understands what that means, but it may not make sense to catch all.
Avoid catching everything too soon, exceptions exist to tell you somethings wrong, blanket catching ignores that and can mean your program keeps running, but starts behaving wrong, possibly corrupting data. Its often better to "fail early and fail fast" when receiving unexpected exceptions.
As others have said - No - you dont need to catch the specific exception, catching Exception or just catch will prevent the exception from bubbling up.
However you should just catch specific exceptions where possible to make your code more explicit in what it is doing. Better again test for correctness before the potential error condition - again this is covered in other posts.
For your specific problem the link you posted seems to indicate that it is a problem with reading values from the isolated storage (IsolatedStorage.get_Item) - so wherever you access IsolatedStorage during from the ScheduledTaskAgent invocation you need to ensure the item exists before getting it. Perhaps there are some config settings missing or something?

Exception handling within an Exception in C#

i know this could be a little weird but a doubt is a doubt afterall...
what would happen in the following situation...
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
//so i will handle that exception over here
//and since an exception occurred while sending a mail
//i will log an event with the eventlog
//All i want to know is what if an exception occurs here
//while writing the error log, how should i handle it??
}
}
Thank you.
I would personally wrap the call to write to event log with another try\catch statement.
However, ultimately it depends on what your specification is. If it is critical to the system that the failure is written to the event log then you should allow it to be thrown. However, based on your example, I doubt this is what you want to do.
You can simply catch errors in the error logging method. However I wouldn't personally do that, as broken error logging is a sign your application can't function at all.
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
WriteToLog();
}
}
private void WriteToLog()
{
try
{
// Write to the Log
}
catch(Exception ex)
{
// Error Will Robinson
// You should probably make this error catching specialized instead of pokeman error handling
}
}
Each exception is caught only when inside a try-catch block. You could nest try-catch but is generally not a good idea.
You could add a try-catch block in your catch block as well.
Considering the kind of exceptions when writing to a file (rights, disk space...) I would advice not to handle it in here. If it fails the first time, there's good chance you won't be able to write to the event log that it's not possible to write in the event log...
Let it bubble up and be handled by an upper level try/catch.
Chris S. has the best answer. Placing a try-catch block inside a catch block is very rarely a good idea. and in your case it will just convolute your code. If you check to see if you were successful in writing to your log file here, you will have to do it in every place where you try to write into your log file. You can easily avoid this unnecessary code duplication by having all your individual modules be self contained when it comes to notifying/handling of error conditions within these modules. When sending your mail fails you perform the proper actions inside your catch block to handle this exceptional condition like:
disposing of the contents of your mail object
making sure your socket is closed
writing an entry into your log file to note the error
Inside your catch block just call whatever API you have defined to writing a log entry into your logfile and forget about about the rest. Inside your logging API is where you should handle any logging related exceptional cases (the disk is full, no permission to write to file, file not found, etc...). Your mailing module does not need to know if the logging was successful or not, that responsibility should be delegated to the logging module.
I personally handle this situation using a simple extension method.
public static class MyExtentions
{
public static void LogToErrorFile(this Exception exception)
{
try
{
System.IO.File.AppendAllText(System.IO.Path.Combine(Application.StartupPath, "error_log.txt"),
String.Format("{0}\tProgram Error: {1}\n", DateTime.Now, exception.ToString()));
}
catch
{
// Handle however you wish
}
}
}
The usage is simple:
try
{
...
}
catch(Exception ex)
{
ex.LogToErrorFile();
}
You can then handle the caught exception inside the extension method however you want, or simply don't catch it and let it bubble up to the top. I've found this design to be a simple, reproducible way to handle exceptions throughout the application.
Firstly I would say don't catch "Exception" in catch block. You could instead, for mailing, check for all validity and then catch specific exception(SmtpException, ) that you can do something about(and informing user with a friendly message). Throwing exception from your code and informing the UI about is not a bad idea. If your methods accepts inputs with certain specification and if they are not met, your method should/can throw error and inform user about it.
For exceptions that have no control over, use global handling exception, like Application_Error for web.
Getting Better Information on Unhandled Exceptions Peter Bromberg explains this better.
Also for any privildged resource you are accessing, like eventlogs, make sure you assembly has access to it.
Useful links Build a Really Useful ASP.NET Exception Engine By Peter A. Bromberg
and
Documenting Exceptional Developers By Peter A. Bromberg
For web application look into
Health monitoring
Exception logging
One more thing, if your application goes wrong/ throws error that can't handle( at all) its better to let it go down gracefully and not continue. Application in unstable state is not good idea.

.NET and C# Exceptions. What is it reasonable to catch

Disclaimer, I'm from a Java background. I don't do much C#. There's a great deal of transfer between the two worlds, but of course there are differences and one is in the way Exceptions tend to be thought about.
I recently answered a C# question suggesting that under some circstances it's reasonable to do this:
try {
some work
} catch (Exeption e) {
commonExceptionHandler();
}
(The reasons why are immaterial). I got a response that I don't quite understand:
until .NET 4.0, it's very bad to catch
Exception. It means you catch various
low-level fatal errors and so disguise
bugs. It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed, so even if the
callExceptionReporter fuunction tries
to log and quit, it may not even get
to that point (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database).
May I'm more confused than I realise, but I don't agree with some of that. Please would other folks comment.
I understand that there are many low level Exceptions we don't want to swallow. My commonExceptionHandler() function could reasonably rethrow those. This seems consistent with this answer to a related question. Which does say "Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown." So I conclude using catch (Exception ) is not always evil, silently swallowing certain exceptions is.
The phrase "Until .NET 4 it is very bad to Catch Exception" What changes in .NET 4? IS this a reference to AggregateException, which may give us some new things to do with exceptions we catch, but I don't think changes the fundamental "don't swallow" rule.
The next phrase really bothers be. Can this be right?
It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database)
My understanding is that if some low level code had
lowLevelMethod() {
try {
lowestLevelMethod();
} finally {
some really important stuff
}
}
and in my code I call lowLevel();
try {
lowLevel()
} catch (Exception e) {
exception handling and maybe rethrowing
}
Whether or not I catch Exception this has no effect whatever on the excution of the finally block. By the time we leave lowLevelMethod() the finally has already run. If the finally is going to do any of the bad things, such as corrupt my disk, then it will do so. My catching the Exception made no difference. If It reaches my Exception block I need to do the right thing, but I can't be the cause of dmis-executing finallys
For the question #2:
The author meant "Corrupted State Exceptions". They will be introduced in .NET 4.0 (CLR team announced this at PDC 2008 in this talk).
Corrupted state exceptions cannot be caught by normal catch block. Examples: Access violation, Invalid Memory.
But you might want to catch these exceptions:
In main() – write to log, exit, turn off addin
Very rare cases when you know that code throws exception like this (e.g. some cases with interop with native code)
To do this you should put attribute [HandleProcessCorruptedStateException] at the method where you want to catch CorruptedStateException.
To read more about these exceptions please see this MSDN article.
As a general rule you shouldn't catch exceptions unless:
You have a specific exception that you can handle and do something about. However in this case you should always check whether you shouldn't be trying to account for and avoid the exception in the first place.
You are at the top level of an application (for instance the UI) and do not want the default behaviour to be presented to the user. For instance you might want an error dialog with a "please send us your logs" style message.
You re-throw the exception after dealing with it somehow, for instance if you roll back a DB transaction.
Your finally blocks always execute. Your code sample is correct - the low level method should just have try and finally. For instance an unmanaged call might know that it needs to dispose of the unmanaged resource, but this wouldn't be exposed to .Net methods calling it. That call should get rid of the unmanaged resource in its finally block, and calling managed methods can handle exceptions or just pass them on up.
If there's something in an exception that you need to handle you should re-throw the exception, for instance:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}
My motto is handle what you can (or need to) and let any other exceptions bubble up and catch them in an UnhandledException event.
You are correct tho, a finally block is always called (even in the event of an exception being raised in the try section) before you exit the method. So whether you want to the catch the exception on the out method or not is entirely up to you.....this should not affect the finally block being called.
Just to your third question:
If you have
nastyLowLevel() {
doSomethingWhichMayCorruptSomethingAndThrowsException();
}
MyEvilCatcher() {
try {
nastyLowLevel();
} catch (Exception e) {
MyExceptionHandler(e);
}
}
WiseCatcher() {
try {
MyEvilCatcher();
} catch (LowLevelException e) {
DoSomethingWiseSoFinnalyDontRuinAnything();
} finally {
DoSomethingWhichAssumesLowLevelWentOk();
}
}
I think the response you asked about just meant that some low level methods could use exceptions to inform some outer method that special care has to be taken. If you forget about this exceptions in your catch-all-handler and don't rethrow them, something might go wrong.
Generally, I prefer thinking carefully about which exceptions can possibly be thrown and catch them explicitely. I only use "generic handler" at the very outer level in production environments in order to log unexpected exception and present them to the customer in an well-formatted manner (including a hint to send us the log file.)
I think the quoted response is wrong (or maybe meant 2.0 instead of 4.0)? It sounds kinda bogus to me.

How does code look when you don't use exceptions to control flow?

I've taken the advice I've seen in other answered questions about when to throw exceptions but now my APIs have new noise. Instead of calling methods wrapped in try/catch blocks (vexing exceptions) I have out argument parameters with a collection of errors that may have occurred during processing. I understand why wrapping everything in a try/catch is a bad way to control the flow of an app but I rarely see code anywhere that reflects this idea.
That's why this whole thing seems so strange to me. It's a practice that is supposedly the right way to code but I don't see it anywhere. Added to that, I don't quite understand how to relate to client code when "bad" behavior has occured.
Here's a snippet of some code I'm hacking around with that deals with saving pictures that are uploaded by users of a web app. Don't sweat the details (it's ugly), just see the way I've added these output parameters to everything to get error messages.
public void Save(UserAccount account, UserSubmittedFile file, out IList<ErrorMessage> errors)
{
PictureData pictureData = _loader.GetPictureData(file, out errors);
if(errors.Any())
{
return;
}
pictureData.For(account);
_repo.Save(pictureData);
}
Is this the right idea? I can reasonably expect that a user submitted file is in some way invalid so I shouldn't throw an exception, however I'd like to know what was wrong with the file so I produce error messages. Likewise, any client that now consumes this save method will also want to find out what was wrong with the overall picture saving operation.
I had other ideas about returning some status object that contained a result and additional error messages but that feels weird. I know having out parameters everywhere is going to be hard to maintain/refactor/etc.
I would love some guidance on this!
EDIT: I think the user submitted files snippet may lead people to think of exceptions generated by loading invalid images and other "hard" errors. I think this code snippet is a better illustration of where I think the idea of throwing an exception is being discouraged.
With this I'm just saving a new user account. I do a state validation on the user account and then I hit the persistent store to find out if the username has been taken.
public UserAccount Create(UserAccount account, out IList<ErrorMessage> errors)
{
errors = _modelValidator.Validate(account);
if (errors.Any())
{
return null;
}
if (_userRepo.UsernameExists(account.Username))
{
errors.Add(new ErrorMessage("Username has already been registered."));
return null;
}
account = _userRepo.CreateUserAccount(account);
return account;
}
Should I throw some sort of validation exception? Or should I return error messages?
Despite the performance concerns, I think it's actually cleaner to allow Exceptions to be thrown out of a method. If there are any exceptions that can be handled within your method, you should handle them appropriately, but otherwise, let them bubble up.
Returning errors in out parameters, or returning status codes feels a bit clunky. Sometimes when faced with this situation, I try to imagine how the .NET framework would handle the errors. I don't believe there are many .NET framework methods that return errors in out parameters, or return status codes.
By definition, "exception" means an exceptional circumstance from which a routine cannot recover. In the example you provided, it looks like that means the image was invalid/corrupt/unreadable/etc. That should be thrown and bubbled up to the topmost layer, and there decide what to do with the exception. The exception itself contains the most complete information about what went wrong, which must be available at the upper levels.
When people say you should not use exceptions to control program flow, what they mean is: (for example) if a user tries to create an account but the account already exists, you should not throw an AccountExistsException and then catch it higher up in the application to be able to provide that feedback to the user, because the account already existing is not an exceptional case. You should expect that situation and handle it as part of your normal program flow. If you can't connect to the database, that is an exceptional case.
Part of the problem with your User Registration example is that you are trying to encapsulate too much into a single routine. If your method tries to do more than one thing, then you have to track the state of multiple things (hence things getting ugly, like lists of error messages). In this case, what you could do instead is:
UsernameStatus result = CheckUsernameStatus(username);
if(result == UsernameStatus.Available)
{
CreateUserAccount(username);
}
else
{
//update UI with appropriate message
}
enum UsernameStatus
{
Available=1,
Taken=2,
IllegalCharacters=3
}
Obviously this is a simplified example, but I hope the point is clear: your routines should only try to do one thing, and should have a limited/predictable scope of operation. That makes it easier to halt and redirect program flow to deal with various situations.
I think this is the wrong approach. Yes, it's very likely that you'll get occasional invalid images. But that's still the exceptional scenario. In my opinions, exceptions are the right choice here.
In situations like you have I usually throw a custom exception to the caller. I have a bit of a different view on exceptions maybe than others have: If the method couldn't do what it is intended to do (ie. What the method name says: Create a user account) then it should throw an exception - to me: not doing what you're supposed to do is exceptional.
For the example you posted, I'd have something like:
public UserAccount Create(UserAccount account)
{
if (_userRepo.UsernameExists(account.Username))
throw new UserNameAlreadyExistsException("username is already in use.");
else
return _userRepo.CreateUserAccount(account);
}
The benefit, for me at least, is that my UI is dumb. I just try/catch any function and messagebox the exception message like:
try
{
UserAccount newAccount = accountThingy.Create(account);
}
catch (UserNameAlreadyExistsException unaex)
{
MessageBox.Show(unaex.Message);
return; // or do whatever here to cancel proceeding
}
catch (SomeOtherCustomException socex)
{
MessageBox.Show(socex.Message);
return; // or do whatever here to cancel proceeding
}
// If this is as high up as an exception in the app should bubble up to,
// I'll catch Exception here too
This is similar in style to a lot of System.IO methods (http://msdn.microsoft.com/en-us/library/d62kzs03.aspx) for an example.
If it becomes a performance problem, then I'll refactor to something else later, but I've never needed to squeeze performance out of a business app because of exceptions.
I would allow for exceptions as well but based on your thread your looking for an alternative. Why not include a status or error information in your PictureData object. You can then just return the object with the errors in it and the other stuff left empty. Just a suggestion, but you are pretty much doing exactly what exceptions were made to solve :)
First off, exceptions should never be used as a control-flow mechanism. Exceptions are an error propagation and handling mechanism, but should never be used to control program flow. Control flow is the domain of conditional statements and loops. That is quite often a critical misconception that many programmers make, and is usually what leads to such nightmares when they try to deal with exceptions.
In a language like C# which offers structured exception handling, the idea is to allow 'exceptional' cases in your code to be identified, propagated, and eventually handled. Handling is generally left to the highest level of your application (i.e. a windows client with a UI and error dialogs, a web site with error pages, a logging facility in the message loop of a background service, etc.) Unlike Java, which uses checked exception handling, C# does not require you to specifically handle every single exception that may pass through your methods. On the contrary, trying to do so would undoubtedly lead to some severe performance bottlenecks, as catching, handling, and possibly re-throwing exceptions is costly business.
The general idea with exceptions in C# is that if they happen...and I stress if, because they are called exceptions due to the fact that during normal operation, you shouldn't be encountering any exceptional conditions, ...if they happen then you have the tools at your disposal to safely and cleanly recover and present the user (if there is one) with a notification of the applications failure and possible resolution options.
Most of the time, a well written C# application won't have that many try/catch blocks in core business logic, and will have a lot more try/finally, or better yet, using blocks. For most code, the concern in response to an exception is to recover nicely by releasing resources, locks, etc. and allowing the exception to continue on. In your higher level code, usually in the outer message processing loop of an application or in the standard event handler for systems like ASP.NET, you'll eventually perform your structured handling with a try/catch, possibly with multiple catch clauses to deal with specific errors that need unique handling.
If you are properly handling exceptions and building code that uses exceptions in an appropriate way, you shouldn't have to worry about lots of try/catch/finally blocks, return codes, or convoluted method signatures with lots of ref and out parameters. You should see code more like this:
public void ClientAppMessageLoop()
{
bool running = true;
while (running)
{
object inputData = GetInputFromUser();
try
{
ServiceLevelMethod(inputData);
}
catch (Exception ex)
{
// Error occurred, notify user and let them recover
}
}
}
// ...
public void ServiceLevelMethod(object someinput)
{
using (SomeComponentThatsDisposable blah = new SomeComponentThatsDisposable())
{
blah.PerformSomeActionThatMayFail(someinput);
} // Dispose() method on SomeComponentThatsDisposable is called here, critical resource freed regardless of exception
}
// ...
public class SomeComponentThatsDisposable: IDosposable
{
public void PErformSomeActionThatMayFail(object someinput)
{
// Get some critical resource here...
// OOPS: We forgot to check if someinput is null below, NullReferenceException!
int hash = someinput.GetHashCode();
Debug.WriteLine(hash);
}
public void Dispose()
{
GC.SuppressFinalize(this);
// Clean up critical resource if its not null here!
}
}
By following the above paradigm, you don't have a lot of messy try/catch code all over, but your still "protected" from exceptions that otherwise interrupt your normal program flow and bubble up to your higher-level exception handling code.
EDIT:
A good article that covers the intended use of exceptions, and why exceptions aren't checked in C#, is the following interview with Anders Heijlsberg, the chief architect of the C# language:
http://www.artima.com/intv/handcuffsP.html
EDIT 2:
To provide a better example that works with the code you posted, perhaps the following will be more useful. I'm guessing at some of the names, and doing things one of the ways I've encountered services implemented...so forgive any license I take:
public PictureDataService: IPictureDataService
{
public PictureDataService(RepositoryFactory repositoryFactory, LoaderFactory loaderFactory)
{
_repositoryFactory = repositoryFactory;
_loaderFactory = loaderFactory;
}
private readonly RepositoryFactory _repositoryFactory;
private readonly LoaderFactory _loaderFactory;
private PictureDataRepository _repo;
private PictureDataLoader _loader;
public void Save(UserAccount account, UserSubmittedFile file)
{
#region Validation
if (account == null) throw new ArgumentNullException("account");
if (file == null) throw new ArgumentNullException("file");
#endregion
using (PictureDataRepository repo = getRepository())
using (PictureDataLoader loader = getLoader())
{
PictureData pictureData = loader.GetPictureData(file);
pictureData.For(account);
repo.Save(pictureData);
} // Any exceptions cause repo and loader .Dispose() methods
// to be called, cleaning up their resources...the exception
// bubbles up to the client
}
private PictureDataRepository getRepository()
{
if (_repo == null)
{
_repo = _repositoryFactory.GetPictureDataRepository();
}
return _repo;
}
private PictureDataLoader getLoader()
{
if (_loader == null)
{
_loader = _loaderFactory.GetPictureDataLoader();
}
return _loader;
}
}
public class PictureDataRepository: IDisposable
{
public PictureDataRepository(ConnectionFactory connectionFactory)
{
}
private readonly ConnectionFactory _connectionFactory;
private Connection _connection;
// ... repository implementation ...
public void Dispose()
{
GC.SuppressFinalize(this);
_connection.Close();
_connection = null; // 'detatch' from this object so GC can clean it up faster
}
}
public class PictureDataLoader: IDisposable
{
// ... Similar implementation as PictureDataRepository ...
}

Is this a bad practice to catch a non-specific exception such as System.Exception? Why?

I am currently doing a code review and the following code made me jump. I see multiple issues with this code. Do you agree with me? If so, how do I explain to my colleague that this is wrong (stubborn type...)?
Catch a generic exception (Exception ex)
The use of "if (ex is something)" instead of having another catch block
We eat SoapException, HttpException and WebException. But if the Web Service failed, there not much to do.
Code:
try
{
// Call to a WebService
}
catch (Exception ex)
{
if (ex is SoapException || ex is HttpException || ex is WebException)
{
// Log Error and eat it.
}
else
{
throw;
}
}
The mantra is:
You should only catch exceptions if
you can properly handle them
Thus:
You should not catch general
exceptions.
In your case, yes, you should just catch those exceptions and do something helpful (probably not just eat them--you could throw after you log them).
Your coder is using throw (not throw ex) which is good.
This is how you can catch multiple, specific exceptions:
try
{
// Call to a WebService
}
catch (SoapException ex)
{
// Log Error and eat it
}
catch (HttpException ex)
{
// Log Error and eat it
}
catch (WebException ex)
{
// Log Error and eat it
}
This is pretty much equivalent to what your code does. Your dev probably did it that way to avoid duplicating the "log error and eat it" blocks.
I am currently doing a code review and the following code made me jump. I see multiple issues with this code. Do you agree with me?
Not totally, see below.
Catch a generic exception (Exception ex)
In general, catching a generic exception is actually ok as long as you rethrow it (with throw;) when you come to the conclusion that you can't handle it. The code does that, so no immediate problem here.
The use of "if (ex is something)" instead of having another catch block
The net effect of the catch block is that only SoapException, HttpException, etc. are actually handled and all other exceptions are propagated up the call stack. I guess functionality-wise this is what the code is supposed to do, so there's no problem here either.
However, from a aesthetics & readability POV I would prefer multiple catch blocks to the "if (ex is SoapException || ..)". Once you refactor the common handling code into a method, the multiple catch blocks are only slightly more typing and are easier to read for most developers. Also, the final throw is easily overlooked.
We eat SoapException, HttpException and WebException. But if the Web Service failed, there not much to do.
Here possibly lurks the biggest problem of the code, but it's hard to give advice without knowing more about the nature of the application. If the web service call is doing something that you depend on later then it's probably wrong to just log & eat the exceptions. Typically, you let the exception propagate to the caller (usually after wrapping it into e.g. a XyzWebServiceDownException), maybe even after retrying the webservice call a few times (to be more robust when there are spurious network issues).
The problem with catching and re-throwing the same exception is that, although .NET does its best to keep the stack trace intact, it always ends up getting modified which can make tracking down where the exception actually came from more difficult (e.g. the exception line number will likely appear to be the line of the re-throw statement rather than the line where the exception was originally raised). There's a whole load more information about the difference between catch/rethrow, filtering, and not catching here.
When there is duplicate logic like this, what you really need is an exception filter so you only catch the exception types you're interested in. VB.NET has this functionality, but unfortunately C# doesn't. A hypothetical syntax might look like:
try
{
// Call to a WebService
}
catch (Exception ex) if (ex is SoapException || ex is HttpException || /* etc. */)
{
// Log Error and eat it
}
As you can't do this though, what I tend to do instead is use a lambda expression for the common code (you could use a delegate in C# 2.0), e.g.
Action<Exception> logAndEat = ex =>
{
// Log Error and eat it
};
try
{
// Call to a WebService
}
catch (SoapException ex)
{
logAndEat(ex);
}
catch (HttpException ex)
{
logAndEat(ex);
}
catch (WebException ex)
{
logAndEat(ex);
}
I would like to add here, because the Exception handling in almost all java / C# code that I have seen is just incorrect. I.e. you end up with very difficult to debug error for ignored Exceptions, or, equally bad, you get an obscure exception which tells you nothing, because blindly following the "catching(Exception) is bad" and things are just worse.
First, understand that an exception is a way to facilitate the returning of error information across code layers. Now, mistake 1: a layer is not just a stack frame, a layer is code which has a well defined responsibility. If you just coded interfaces and impls just because, well you have better things to fix.
If the layers are well designed and have specific responsibilities, then the information of the error has different meaning as it bubbles up. <-this is the key on what to do, there is no universal rule.
So, this means that when an Exception occurs you have 2 options, but you need to understand where in the layer you are:
A) If you are in the middle of a layer, and you are just an internal, normally private, helper function and something goes bad: DONT WORRY, let the caller receive the exception. Its perfectly OK because you have no business context and
1) You are not ignoring the error and
2) The caller is part of your layer and should have known this can happen, but you might not now the context to handle it down below.
or ...
B) You are the top boundary of the layer, the facade to the internals. Then if you get an exception the default shall be to CATCH ALL and stop any specific exceptions from crossing to the upper layer which will make no sense to the caller, or even worse, you might change and the caller will have a dependency to an implementation detail and both will break.
The strength of an application is the decoupling level between the layers. Here you will stop everything as a general rule and rethrow the error with a generic exception translating the information to a more meaningful error for the upper layer.
RULE: All entry points to a layer shall be protected with CATCH ALL and all errors translated or handled. Now this 'handeled' happens only 1% of the time, mostly you just need (or can) return the error in a correct abstraction.
No I am sure this is very difficult to understand. real Example ->
I have a package that runs some simulations. These simulations are in text scripts. there is a package that compiles these scripts and there is a generic utils package that just reads text files and, of course, the base java RTL. The UML dependency is->
Simulator->Compiler->utilsTextLoader->Java File
1) If something breaks in the utils loader inside one private and I get a FileNotFound, Permissions or what ever, well just let it pass. There is nothing else you can do.
2) At the boundary, in the utilsTextLoader function initially called you will follow the above rule and CATCH_ALL. The compiler does not care on what happen, it just needs to now whether the file was loaded or not. So in the catch, re throw a new exception and translate the FileNotFound or whatever to "Could not read file XXXX".
3) The compiler will now know that the source was not loaded. Thats ALL it needs to know. So if I later I change utilsTestLoader to load from network the compiler will not change. If you let go FileNotFound and later change you will impact compiler for nothing.
4) The cycle repeats: The actual function that called the lower layer for the file will do nothing upon getting the exception. So it lets it go up.
5) As the exception gets to the layer between simulator and compiler the compiler again CATCHES_ALL, hiding any detail and just throws a more specific error: "Could not compile script XXX"
6) Finally repeat the cycle one more time, the simulator function that called the compiler just lets go.
7) The finally boundary is to the user. The user is a LAYER and all applies. The main has a try that catches_ALL and finally just makes a nice dialog box or page and "throws" a translated error to the user.
So the user sees.
Simulator: Fatal error could not start simulator
-Compiler: Could not compile script FOO1
--TextLoader: Could not read file foo1.scp
---trl: FileNotFound
Compare to:
a) Compiler: NullPointer Exception <-common case and a lost night debugging a file name typo
b) Loader: File not found <- Did I mention that loader loads hundreds of scripts ??
or
c) Nothing happens because all was ignored!!!
Of course this assumes that on every rethrow you didn't forget to set the cause exception.
Well my 2cts. This simple rules have saved my life many times...
-Ale
Sometimes that is to only way to handle "catch every exception" scenarios, without actually catching every exception.
I think sometimes, say, lowlevel framework / runtime code needs to make sure that no exception is ever escaping. Unfortunately, there is also no way the framework code can know which exceptions are raised by the code executed by the thread.
In that case a possible catch block could look like this:
try
{
// User code called here
}
catch (Exception ex)
{
if (ExceptionIsFatal(ex))
throw;
Log(ex);
}
There are three important points here, however:
This isn't something for every situation. In code reviews we are very picky about places where this is actually neccessary and thus allowed.
The ExceptionIsFatal() method assures that we don't eat exceptions which should never be swallowed (ExecutionEngineException, OutOfMemoryException, ThreadAbortException, etc.)
What is swallowed is carefully logged (event-log, log4net, YMMV)
Typically, I'm all for the practice of letting uncaught exceptions simply "crash" the application by terminating the CLR. However, especially in server applications, this is sometimes not sensible. If one thread encounters a problem which is deemed non-fatal, there is no reason in ripping the whole process down, killing off all other running requests (WCF, for example, handles some cases this way).
You should usually still catch generic exceptions in a global handler (which is the perfect place to log unexpected Exceptions), but otherwise as said before, you should only catch specific exception types in other places if you plan to do something with them. The catch blocks should look for those exception types explicitly, not as the code you posted does.
I don't think this is such a bad thing in this case, but I also do something similar in my code with exceptions that can be safely ignored being caught and the rest being re-thrown. As noted by Michael's response, having each catch being a separate block could cause some readability issues which are prevented by going this route.
In regards to pointing this out to your colleague, I think you would have a hard time convincing them that this is the wrong way of doing things - even more so if they are stubborn - because of the potential readability issues with doing things the other way. Since this version is still throwing the generic exception's that can't be handled it is in keeping with the spirit of the practice. However, if the code was in line with the following:
try
{
// Do some work
}
catch (Exception ex)
{
if (ex is SoapException)
{
// SoapException specific recovery actions
}
else if (ex is HttpException)
{
// HttpException specific recovery actions
}
else if (ex is WebException)
{
// WebException specific recoery actions
}
else
{
throw;
}
}
Then I think you would have a bit more of a reason to be concerned as there is no point in doing work for a specific exception by checking for it in a general exception block.
the princeple is only to catch the exception you can handle.
such as, if you know how to deal with findnotfound, you catch the filenotfoundexception, otherwiese, do NOT catch it and let it be thrown to the upper layer.

Categories