IOException vs checking File.Exists? - c#

(I've searched similar threads and couldn't find anything that addressed this particular issue, though there were several similar such as here and here.)
I'm evaluating performance of our app and I'm noticing that we're getting some IOExceptions "Cannot locate resource". I'm not sure exactly how many times it's happening (largely depends on how user uses the app), but it's at least a dozen or so.
I'm assuming that exceptions in general are performance expensive as are File I/O calls like File.Exists(). I know that it's always good practice to check if a file exists before you try and load it. My question is, how much performance gain would I see if I check if this particular file existed? (Again, ignore the "you should do this anyway", I'm just trying to get an understanding of performance).
Option 1:
try
{
return (ResourceDictionary) Application.LoadComponent(uri);
}
catch (Exception)
{
//If it's not there, don't do anything
}
This doesn't make an extra IO call, but sometimes throws and exception which is swallowed.
Option 2:
if(File.Exists(uri))
{
return (ResourceDictionary) Application.LoadComponent(uri);
}

In general, if the file should exist (ie: it's part of your application's deployment), then I'd use the exception checking, and nothing else. This is because, in this case, the exception is truly an exceptional and unexpected circumstance.
If the file is something that is input by the user, checking for existence becomes potentialy meaningful. However, this still doesn't eliminate the need for exception handling, as the file could be deleted between the time you check and the time you open/use it. As such, you'd still need the exception handling - in which case you may want to still just use your first option code, but make sure the exception handling is clean enough to always provide a behavior, even if the file doesn't exist.

I can't see there being a big performance difference between your two options. Most of the work is locating and reading the file so in both cases you have to do that. What might be useful is caching the result if you don't expect the user add/remove this file while the application is running. So you might do something like
private static Dictionary<Uri, ResourceDictionary> _uriToResources =
new Dictionary<Uri, ResourceDictionary>();
public static ResourceDictionary GetResourceDictionary(Uri uri)
{
ResourceDictionary resources;
if (_uriToResources.TryGetValue(uri, out resources))
{
return resources;
}
try
{
resources = (ResourceDictionary)Application.LoadComponent(uri);
}
catch
{
// could prompt/alert the user here.
resources = null; // or an appropriate default.
}
_uriToResources[uri] = resources;
return resources;
}
This would prevent you from repetitively trying to load a resource that does not exist. Here I return a null object but it may be better to use some default as a fallback.

File.Exists does internally throw exceptions as well. So the performance will be very similar.
Here is the code from File.cs which contains the helper method which File.Exists calls.
[SecurityCritical]
private static bool InternalExistsHelper(string path, bool checkHost)
{
try
{
if (path == null || path.Length == 0)
return false;
path = Path.GetFullPathInternal(path);
if (path.Length > 0 && Path.IsDirectorySeparator(path[path.Length - 1]))
return false;
FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, path, false, false);
return File.InternalExists(path);
}
catch (ArgumentException ex)
{
}
catch (NotSupportedException ex)
{
}
catch (SecurityException ex)
{
}
catch (IOException ex)
{
}
catch (UnauthorizedAccessException ex)
{
}
return false;
}

Related

What is the purpose of using the following try-catch block? c# [duplicate]

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.

try catch block or boolean flag?

I'm not sure about my code, I want to save first into Blob Azure and if it was successful then save that url into my database, I have two ways to do this. The first one using a boolean variable named flag, if flag value is set to true then I can save it into my database, but I'm not sure if this code is the best approach. Is it possible that for some reason the file is not uploaded to Blob and even if that happens flag value is set to true?:
First approach using boolean flag variable :
using (Stream fileStream = file.InputStream)
{
blockBlob.UploadFromStream(fileStream);
flag = true;
}
if (flag == true)
{
Urls.Add(blockBlob.SnapshotQualifiedUri.ToString());
db.Save();
}
Or should be a better approach to use a try catch block?
try
{
using (Stream fileStream = file.InputStream)
{
blockBlob.UploadFromStream(fileStream);
}
}
catch(Exception)
{
//do something
}
Urls.Add(blockBlob.SnapshotQualifiedUri.ToString());
db.Save();
Please explain in your answer the differences between each approach, personally I think that a try catch should be a better approach but I want to confirm in here :)
Normally incases like this, I go a combination of the two and create a method that handles the upload and returns true or false depending on whether the upload was successful, or an exception occurred.
The try catch allows for any potential exceptions to handled appropriately, and the flag becomes simply an indicator to inform you whether the process succeeded or not.
For example, for your upload code, I would create an extension method like this:
public static bool TryUploadFile(this CloudBlockBlob blockBlob, File file)
try
{
using (Stream fileStream = file.InputStream)
{
blockBlob.UploadFromStream(fileStream);
}
return true;
}
catch(Exception)
{
//do some logging or other error handling
}
return false;
}
And then call the method like so:
bool succeeded = blockBlob.TryUploadFile(file);
if (succeeded)
{
Urls.Add(blockBlob.SnapshotQualifiedUri.ToString());
db.Save();
}
Generally the decision about whether to use exceptions or a return value that indicates whether the function succeeds depends on the chances of failure of the function.
Exception handling is fairly expensive, but if it is only used in exceptional cases then this should not lead to performance problems.
The advantage of exception handling is that it makes your code look much cleaner, better to understand and easier to maintain and change.
The lack of a return value that indicated whether the action succeeded or not, usually gives an indication that it is quite exceptional that the action does not succeed. This in contrary to, for instance, opening a file, which quite often might fail and thus uses a return value to report failure.
All three functions you use, UploadFromStream, Add, and Save do not use a return value indicating success (or at least you don't think you need these return values), so it is assumed that these functions seldom fail.
In such cases I'd use the exception method. The code could would look much cleaner:
public void Upload(...)
{
try
{
using (Stream fileStream = file.InputStream)
{
blockBlob.UploadFromStream(fileStream);
}
Urls.Add(blockBlob.SnapshotQualifiedUri.ToString());
db.Save();
}
catch(Exception exc)
{
ProcessProblem(exc);
throw new MyUploadException(..., exc);
// or just throw exc
}
}
Now your code looks fairly straightforward. You don't have to remember your progress using temporary variables, and if anything goes wrong, your logging will happen. Note that this will even be the case if the exception is thrown on unexpected places, like when the Dispose at the end of your using statement goes wrong!
This function is also better maintainable. If you add an extra function where it is also fairly exceptional that it fails, just add it, and your catch block will handle the problems.
So the basic rule: if failure is exceptional, use exceptions. Otherwise use return values.

How to properly handle exceptions when working with files in C#

I've read many blogs/articles/book chapters about proper exception handling and still this topic is not clear to me. I will try to illustrate my question with following example.
Consider the class method that has following requirements:
receive list of file paths as parameter
read the file content for each file or skip if there is any problem trying to do that
return list of objects representing file content
So the specs are straightforward and here is how I can start coding:
public class FileContent
{
public string FilePath { get; set; }
public byte[] Content { get; set; }
public FileContent(string filePath, byte[] content)
{
this.FilePath = filePath;
this.Content = content;
}
}
static List<FileContent> GetFileContents(List<string> paths)
{
var resultList = new List<FileContent>();
foreach (var path in paths)
{
// open file pointed by "path"
// read file to FileContent object
// add FileContent to resultList
// close file
}
return resultList;
}
Now note that the 2. from the specs says that method should "skip any file which content can't be read for some reason". So there could be many different reasons for this to happen (eg. file not existing, file access denied due to lack of security permissions, file being locked and in use by some other application etc...) but the point is that I should not care what the reason is, I just want to read file's content if possible or skip the file if not. I don't care what the error is...
So how to properly implement this method then?
OK the first rule of proper exception handling is never catch general Exception. So this code is not good then:
static List<FileContent> GetFileContents(List<string> paths)
{
var resultList = new List<FileContent>();
foreach (var path in paths)
{
try
{
using (FileStream stream = File.Open(path, FileMode.Open))
using (BinaryReader reader = new BinaryReader(stream))
{
int fileLength = (int)stream.Length;
byte[] buffer = new byte[fileLength];
reader.Read(buffer, 0, fileLength);
resultList.Add(new FileContent(path, buffer));
}
}
catch (Exception ex)
{
// this file can't be read, do nothing... just skip the file
}
}
return resultList;
}
The next rule of proper exception handlig says: catch only specific exceptions you can handle. Well I do not I care about handling any specific exceptions that can be thrown, I just want to check if file can be read or not. How can I do that in a proper, the best-practice way?
Although it's generally not considered to be good practice to catch and swallow non-specific exceptions, the risks are often overstated.
After all, ASP.NET will catch a non-specific exception that is thrown during processing of a request, and after wrapping it in an HttpUnhandledException, will redirect to an error page and continue happily on it's way.
In your case, if you want to respect the guideline, you need a complete list of all exceptions that can be thrown. I believe the following list is complete:
UnauthorizedAccessException
IOException
FileNotFoundException
DirectoryNotFoundException
PathTooLongException
NotSupportedException (path is not in a valid format).
SecurityException
ArgumentException
You probably won't want to catch SecurityException or ArgumentException, and several of the others derive from IOException, so you'd probably want to catch IOException, NotSupportedException and UnauthorizedAccessException.
Your requirements are clear - skip files that cannot be read. So what is the problem with the general exception handler? It allows you to perform your task in a manner that is easy, clean, readable, scalable and maintainable.
If at any future date you want to handle the multiple possible exceptions differently, you can just add above the general exception the catch for the specific one(s).
So you'd rather see the below code? Note, that if you add more code to handle the reading of files, you must add any new exceptions to this list. All this to do nothing?
try
{
// find, open, read files
}
catch(FileNotFoundException) { }
catch(AccessViolation) { }
catch(...) { }
catch(...) { }
catch(...) { }
catch(...) { }
catch(...) { }
catch(...) { }
Conventions are guidelines and great to try to adhere to to create good code - but do not over-complicate code just to maintain some odd sense of proper etiquette.
To me, proper etiquette is to not talk in bathrooms - ever. But when the boss says hello to you in there, you say hello back. So if you don't care to handle multiple exceptions differently, you don't need to catch each.
Edit: So I recommend the following
try
{
// find, open, read files
}
catch { } // Ignore any and all exceptions
The above tells me to not care which exception is thrown. By not specifying an exception, even just System.Exception, I've allowed .NET to default to it. So the below is the same exact code.
try
{
// find, open, read files
}
catch(Exception) { } // Ignore any and all exceptions
Or if you're going to log it at least:
try
{
// find, open, read files
}
catch(Exception ex) { Logger.Log(ex); } // Log any and all exceptions
My solution to this question is usually based on the number of possible exceptions. If there are only a few, I specify catch blocks for each. If there are many possible, I catch all Exceptions. Forcing developers to always catch specific exceptions can make for some very ugly code.
You are mixing different actions in one method, changing your code will make you question easier to awnser:
static List<FileContent> GetFileContents(List<string> paths)
{
var resultList = new List<FileContent>();
foreach (var path in paths)
{
if (CanReadFile(path){
resultList.Add(new FileContent(path, buffer));
}
return resultList;
}
static bool CanReadFile(string Path){
try{
using (FileStream stream = File.Open(path, FileMode.Open))
using (BinaryReader reader = new BinaryReader(stream))
{
int fileLength = (int)stream.Length;
byte[] buffer = new byte[fileLength];
reader.Read(buffer, 0, fileLength);
}
}catch(Exception){ //I do not care what when wrong, error when reading from file
return false;
}
return true;
}
This way the CanReadFile hides the implementation for your check. The only thing you have to think about is if the CanReadFile method is correct, or if it needs errorhandling.
Something you can consider in this instance is that between the FileNotFoundException, which you can't catch because there are too many of them, and the most general Exception, there is still the layer IOException.
In general you will try to catch your exceptions as specific as possible, but especially if you are catching the exceptions without actually using them to throw an error, you might as well catch a group of exceptions. Even then however you will try to make it as specific as possible
In my opinion, divide the exceptions up into three types. First are exception you expect and know how to recover. Second are exceptions which you know you can avoid at runtime. Third are those which you don't expect to occur during runtime, but can't avoid or can't realistically handle.
Handle the first type, these are the class of exceptions which are valid to your specific level of abstraction, and which represent valid business cases for recovering at that level (in your case, ignoring.)
The second class of exceptions should be avoided- don't be lazy. The third class of exceptions should be let to pass... you need to make sure you know how to handle a problem, else you may leave your application in a confusing or invalid state.
As others have said, you can handle multiple exceptions by adding more catch blocks to an existing try block, they evaluate in the order they appear, so if you have to handle exceptions which derive from other exceptions, which you also handle, use the more specific one first.
This repeats what is said but hopefully in a way for you to better understand.
You have a logic error in "skip any file which content can't be read for some reason".
If that reason is an error in your code you don't want to skip it.
You only want to skip files that have file related errors.
What if the ctor in FileContent was throwing an error?
And exceptions are expensive.
I would test for FileExists (and still catch exceptions)
And I agree with the exceptions listed by Joe
Come on MSDN has clear examples of how to catch various exceptions

Is a finally block without a catch block a java anti-pattern?

I just had a pretty painful troubleshooting experience in troubleshooting some code that looked like this:
try {
doSomeStuff()
doMore()
} finally {
doSomeOtherStuff()
}
The problem was difficult to troubleshoot because doSomeStuff() threw an exception, which in turn caused doSomeOtherStuff() to also throw an exception. The second exception (thrown by the finally block) was thrown up to my code, but it did not have a handle on the first exception (thrown from doSomeStuff()), which was the real root-cause of the problem.
If the code had said this instead, the problem would have been readily apparent:
try {
doSomeStuff()
doMore()
} catch (Exception e) {
log.error(e);
} finally {
doSomeOtherStuff()
}
So, my question is this:
Is a finally block used without any catch block a well-known java anti-pattern? (It certainly seems to be a not-readily-apparent subclass of the obviously well-known anti-pattern "Don't gobble exceptions!")
In general, no, this is not an anti-pattern. The point of finally blocks is to make sure stuff gets cleaned up whether an exception is thrown or not. The whole point of exception handling is that, if you can't deal with it, you let it bubble up to someone who can, through the relatively clean out-of-band signaling exception handling provides. If you need to make sure stuff gets cleaned up if an exception is thrown, but can't properly handle the exception in the current scope, then this is exactly the correct thing to do. You just might want to be a little more careful about making sure your finally block doesn't throw.
I think the real "anti-pattern" here is doing something in a finally block that can throw, not not having a catch.
Not at all.
What's wrong is the code inside the finally.
Remember that finally will always get executed, and is just risky ( as you have just witnessed ) to put something that may throw an exception there.
There is absolutely nothing wrong a try with a finally and no catch. Consider the following:
InputStream in = null;
try {
in = new FileInputStream("file.txt");
// Do something that causes an IOException to be thrown
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Nothing we can do.
}
}
}
If an exception is thrown and this code doesn't know how to deal with it then the exception should bubble up the call stack to the caller. In this case we still want to clean up the stream so I think it makes perfect sense to have a try block without a catch.
I think it's far from being an anti-pattern and is something I do very frequently when it's critical do deallocate resources obtained during the method execution.
One thing I do when dealing with file handles (for writing) is flushing the stream before closing it using the IOUtils.closeQuietly method, which doesn't throw exceptions:
OutputStream os = null;
OutputStreamWriter wos = null;
try {
os = new FileOutputStream(...);
wos = new OutputStreamWriter(os);
// Lots of code
wos.flush();
os.flush();
finally {
IOUtils.closeQuietly(wos);
IOUtils.closeQuietly(os);
}
I like doing it that way for the following reasons:
It's not completely safe to ignore an exception when closing a file - if there are bytes that were not written to the file yet, then the file may not be in the state the caller would expect;
So, if an exception is raised during the flush() method, it will be propagated to the caller but I still will make sure all the files are closed. The method IOUtils.closeQuietly(...) is less verbose then the corresponding try ... catch ... ignore me block;
If using multiple output streams the order for the flush() method is important. The streams that were created by passing other streams as constructors should be flushed first. The same thing is valid for the close() method, but the flush() is more clear in my opinion.
I'd say a try block without a catch block is an anti-pattern. Saying "Don't have a finally without a catch" is a subset of "Don't have a try without a catch".
I use try/finally in the following form :
try{
Connection connection = ConnectionManager.openConnection();
try{
//work with the connection;
}finally{
if(connection != null){
connection.close();
}
}
}catch(ConnectionException connectionException){
//handle connection exception;
}
I prefer this to the try/catch/finally (+ nested try/catch in the finally).
I think that it is more concise and I don't duplicate the catch(Exception).
try {
doSomeStuff()
doMore()
} catch (Exception e) {
log.error(e);
} finally {
doSomeOtherStuff()
}
Don't do that either... you just hid more bugs (well not exactly hid them... but made it harder to deal with them. When you catch Exception you are also catching any sort of RuntimeException (like NullPointer and ArrayIndexOutOfBounds).
In general, catch the exceptions you have to catch (checked exceptions) and deal with the others at testing time. RuntimeExceptions are designed to be used for programmer errors - and programmer errors are things that should not happen in a properly debugged program.
In my opinion, it's more the case that finally with a catch indicate some kind of problem. The resource idiom is very simple:
acquire
try {
use
} finally {
release
}
In Java you can have an exception from pretty much anywhere. Often the acquire throws a checked exception, the sensible way to handle that is to put a catch around the how lot. Don't try some hideous null checking.
If you were going to be really anal you should note that there are implied priorities among exceptions. For instance ThreadDeath should clobber all, whether it comes from acquire/use/release. Handling these priorities correctly is unsightly.
Therefore, abstract your resource handling away with the Execute Around idiom.
Try/Finally is a way to properly free resources. The code in the finally block should NEVER throw since it should only act on resources or state that was acquired PRIOR to entry into the try block.
As an aside, I think log4J is almost an anti-pattern.
IF YOU WANT TO INSPECT A RUNNING PROGRAM USE A PROPER INSPECTION TOOL (i.e. a debugger, IDE, or in an extreme sense a byte code weaver but DO NOT PUT LOGGING STATEMENTS IN EVERY FEW LINES!).
In the two examples you present the first one looks correct. The second one includes the logger code and introduces a bug. In the second example you suppress an exception if one is thrown by the first two statements (i.e. you catch it and log it but do not rethrow. This is something I find very common in log4j usage and is a real problem of application design. Basically with your change you make the program fail in an way that would be very hard for the system to handle since you basically march onward as if you never had an exception (sorta like VB basic on error resume next construct).
try-finally may help you to reduce copy-paste code in case a method has multiple return statements. Consider the following example (Android Java):
boolean doSomethingIfTableNotEmpty(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT * FROM table", null);
if (cursor != null) {
try {
if (cursor.getCount() == 0) {
return false;
}
} finally {
// this will get executed even if return was executed above
cursor.close();
}
}
// database had rows, so do something...
return true;
}
If there was no finally clause, you might have to write cursor.close() twice: just before return false and also after the surrounding if clause.
I think that try with no catch is anti-pattern. Using try/catch to handle exceptional conditions (file IO errors, socket timeout, etc) is not an anti-pattern.
If you're using try/finally for cleanup, consider a using block instead.

The difference between re-throwing parameter-less catch and not doing anything?

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.

Categories