Designing a class with **Exceptions** - exception

When I design a class I often have trouble deciding if I should throw an exception or have 2 func with the 2nd returning an err value. In the case of 2 functions how should I name the exception and non exception method?
For example if I wrote a class that decompresses a stream and the stream had errors or incomplete I would throw an exception. However what if the app is trying to recover data from the stream and excepts an error? It would want a return value instead? So how should I name the 2nd function?
Or should I not have both an exception method and a nonexception method?

Or should I not have both an exception method and a nonexception method?
That. Unless you really have time to burn maintaining two separate but mostly-identical methods.
If you really need to allow for clients that won't consider errors exceptional, then just indicate them with a return value and be done with it... Otherwise, just write the exception-throwing version and let the odd error-eating client handle the exception.

It depends on the language, but...
In my opinion, two versions of each potentially failing method imposes too high a cognitive burden on the API user, and too high a burden on the API maintainer. My personal preference is for exceptions, since that's fewer parameters to remember the order of.

I believe that you should try to use exceptions even if you're not going to exit program in some cases. You just need to create a specific exception type for your errors. And catch only them when you need to do some spefic logic. All other exceptions will go to upper level of your code.
For example you've created function which throws exception on any error. And you don't want to exit program if user specified incorrect file name. Here is how it can look:
## this is top level try/catch block
try {
## your main code is here
...
## somewhere deep in your code
try {
## we trying to open file specified by user
}
catch (FileNotFoundException) {
## we are not going to exit on this error
## let's just show a user an error message
## and try to ask different file to open
}
} catch (Exception) {
## catch all exceptions here
## the best thing we can do here is save exception to log and quit }
}
We just need to create hierarchy of exceptions (if your language allows it):
Exception <-- MoreSpecificException
This approach is used in Java

Exceptions should normally be used for exceptional conditions, whatever they may be. Being unable to decompress a file is probably an exceptional condition (unless, for example, you're writing a program to scan for badly compressed files). Bad data may or may not be exceptional.
If you've got a class decompressing a stream, then what it should do is decompress the stream, and not try to interpret its contents. Another class should use the first class to get decompressed input, and do the interpretation. That gives you separation of functionality, and good cohesion. Avoid classes where you're tempted to put an "And" in their names: "DecompressAndParseInput" is a bad class name.
Given two classes, there's no particular reason why you have to use the same error-reporting
method for both. The decompressor could throw, and the parser could return an error code.

I would only throw an exception on the decompression function if the results were not usable. If they were usable, return the results and then the function that reads those results can throw an exception instead. IE
try
{
results = decompress(file); // only throws exceptions on non-usable files
} catch (FileNotFoundException) {
// file was not usable, can't recover anything, insert nuclear error handling here
}
try
{
read(results);
} catch (ErrorThatIsRecoverableException) {
partialRead(results);
}
so read() is the function you call on normal data, partialRead is the function that handles trying to recover screwed-up-but-still-usable data. And of course, you don't necessarily need exceptions or separate functions at all- you could do the error handling all within the read() function.

Related

Grails 2.4.4: How to reliably rollback in a complex service method

Consider the following service (transactional by default). A player must always have one account. A player without at least one corresponding account is an error state.
class playerService {
def createPlayer() {
Player p new Player(name: "Stephen King")
if (!p.save()) {
return [code: -1, errors:p.errors]
}
Account a = new Account(type: "cash")
if (!a.save()) {
// rollback p !
return [code: -2, errors:a.errors]
}
// commit only now!
return [code: 0, player:p]
}
}
I have seen this pattern by experienced grails developers, and when I tell them that if creation of the account of the player fails for any reason, it wont rollback the player, and will leave the DB in an invalid state, they look at me like I am mad because grails handles rolling back the player because services are transactional right?
So then, being a SQL guy, I look for a way to call rollback in grails. There isn't one. According to various posts, there are only 2 ways to force grails to rollback in a service:
throw an unchecked exception. You know what this is right?
don't use service methods or transactional annotations, use this construct:
.
DomainObject.withTransaction {status ->
//stuff
if (someError) {
status.setRollbackOnly()
}
}
1. throw an unchecked exception
1.1 So we must throw runtime exceptions to rollback. This is ok for me (I like exceptions), but this wont gel with the grails developers we have who view exceptions as a throwback to Java and is uncool. It also means we have to change the whole way the app currently uses its service layer.
1.2 If an exception is thrown, you lose the p.errors - you lose the validation detail.
1.3 Our new grails devs don't know the difference between an unchecked and an checked exception, and don't know how to tell the difference. This is really dangerous.
1.4. use .save(failOnError: true)
I am a big fan of using this, but its not appropriate everywhere. Sometimes you need to check the reason before going further, not throw an exception. Are the exceptions it can generate always checked, always unchecked, or either? I.e. will failOnError AWLAYS rollback, no matter what the cause? No one I have asked knows the answer to this, which is disturbing, they are using blind faith to avoid corrupted/inconsistent DBs.
1.5 What happens if a controller calls service A, which calls Service B, then service C. Service A must catch any exception and return a nicely formatted return value to the controller. If Service C throws an exception, which is caught by Service A, will service Bs transactions be rolled back? This is critical to know to be able to construct a working application.
UPDATE 1:
Having done some tests, it appears that any runtime exception, even if thrown and caught in some unrelated child calls, will cause everything in the parent to rollback. However, it is not easy to know in the parent session that this rollback has happened - you need to make sure that if you catch any exception, you either rethrow, or pass some notice back to the caller to show that it has failed in such a way that everything else will be rolled back.
2. withTransaction
2.1 This seems a bazaar construct. How do I call this, and what do I pass in for the "status" parameter? What is "setRollbackOnly" exactly. Why is it not just called "rollback". What is the "Only" part? It is tied to a domain object, when your method may want to do update several different domain objects.
2.2 Where are you supposed to put this code? In with the DomainObject class? In the source folder (i.e. not in a service or controller?)? Directly in the controller? (we don't want to duplicate business logic in the controllers)
3. Ideal situation.
3.1 The general case is we want every thing we do in a service method to roll back if anything in that service method cant be saved for any reason, or throws any exception for any reason (checked or unchecked).
3.2 Ideally I would like service methods to "always rollback, unless I explicitly call commit", which is the safest strategy , but this is not possible I believe.
The question is how do I achieve the ideal situation?
Will calling save(failOnError:true) ALWAYS rollback everything, no matter what the reason for failing? This is not perfect, as it is not easy for the caller to know which domain object save caused the issue.
Or do people define lots of exception classes which subclass runtimeException, then explicit catch each of them in the controller to create the appropriate response? This is the old Java way, and our groovy devs pooh pooh this approach due to the amount of boiler plate code we will have to write.
What methods do people use to achieve this?
I wouldn't call myself an expert, and this question is over a year old, but I can answer some of these questions, if only for future searchers. I'm just now refactoring some controllers to use services in order to take advantage of transactions.
I have seen this pattern by experienced grails developers, and when I tell them that if creation of the account of the player fails for any reason, it wont rollback the player, and will leave the DB in an invalid state, they look at me like I am mad because grails handles rolling back the player because services are transactional right?
I'm not seeing in the documentation where it explicitly states that returning from a service method does not rollback the transaction, but I can't imagine that this would be a very sane behavior. Still, testing is an easy way to prove yourself.
1.2 If an exception is thrown, you lose the p.errors - you lose the validation detail.
Since you're the one throwing the exception, you can throw the errors along with it. For instance:
// in service
if (!email.save()) {
throw new ValidationException("Couldn't save email ${params.id}", email.errors)
}
When you catch the exception, you reload the instance (because throwing an exception clears the session), put the errors back into the instance, and then pass that to the view as usual:
// in controller
} catch (ValidationException e) {
def email = Email.read(id)
email.errors = e.errors
render view: "edit", model: [emailInstance: email]
}
This is discussed under the heading "Validation Errors and Rollback", down the page from http://grails.github.io/grails-doc/2.4.4/guide/single.html#transactionsRollbackAndTheSession.
1.4. use .save(failOnError: true) I am a big fan of using this, but its not appropriate everywhere. Sometimes you need to check the reason before going further, not throw an exception. Are the exceptions it can generate always checked, always unchecked, or either? I.e. will failOnError AWLAYS rollback, no matter what the cause? No one I have asked knows the answer to this, which is disturbing, they are using blind faith to avoid corrupted/inconsistent DBs.
failOnError will cause save() to throw a ValidationException, so yes, if you're in a transaction and aren't checking that exception, the transaction will be rolled back.
Generally speaking, it seems to be un-"Grailsy" to use failOnError a lot, probably for the reasons you listed (e.g., lack of control). Instead, you check whether save() failed (if (!save()) ...), and take action based on that.
withTransaction
I'm not sure the point of this, because SpringSource really encourages the use of services for everything. I personally don't like it, either.
If you want to make a particular service non-transactional, and then make one method of it transactional, you can just annotate that one method with #Transactional (unless your developers also dislike annotations because they're too "Java" ;) ).
Note! As soon as you mark a single method with #Transactional, the overall service will become non-transactional.
3.1 The general case is we want every thing we do in a service method to roll back if anything in that service method cant be saved for any reason, or throws any exception for any reason (checked or unchecked).
I feel like checked exceptions are generally considered not "Groovy" (which also makes them not Grails-y). Not sure about the reason for that.
However, it looks like you can tell your service to rollback on your checked exceptions, by listing them in the rollbackFor option to #Transactional.
Or do people define lots of exception classes which subclass runtimeException, then explicit catch each of them in the controller to create the appropriate response? This is the old Java way, and our groovy devs pooh pooh this approach due to the amount of boiler plate code we will have to write.
The nice thing about Groovy is that you can write your boiler plate once and then call it repeatedly. A pattern I've seen a lot, and am currently using, is something like this:
private void validate(Long id, Closure closure) {
try {
closure()
} catch (ValidationException e) {
def email = Email.read(id)
email.errors = e.errors
render view: "edit", model: [emailInstance: email]
} catch (OtherException e) {
def email = Email.read(id)
flash.error = "${e.message}: ${e.reasons}"
render view: "show", model: [emailInstance: email]
} catch (Throwable t) {
flash.error = "Unexpected error $t: ${t.message}"
redirect action: "list"
}
}
And then call it in each controller action like so:
def update(Long id, Long version) {
withInstance(id, version) { Email emailInstance ->
validate(emailInstance.id) {
emailService.update(emailInstance, params)
flash.message = "Email $id updated at ${new Date()}."
redirect action: "show", id: emailInstance.id
}
}
}
(withInstance is another similar method that DRYs up the check for existence and optimistic locking.)
This approach has downsides. You get the same set of redirects in every action; you probably want to write one set of methods for each controller; and it seems kind of silly to pass a closure into a method and expect the method to know what exceptions the closure will throw. But hey, programming's all about tradeoffs, right?
Anyway, hope that is at least interesting.
If you have a service such as:
In a Grails 2 app, the recommended way would be to use transactionStatus.setRollbackOnly().
import grails.transaction.Transactional
Class RoleService {
#Transactional
Role save(String authority) {
Role roleInstance = new Role(authority: authority)
if ( !roleInstance.save() ) {
// log errors here
transactionStatus.setRollbackOnly()
}
roleInstance
}
}
See: https://github.com/grails/grails-core/issues/9212

Why Exception inside a method should be handled within the method itself and not outside?

Consider a method() that throws some exception in its body.
Consider the following scenarios:
Scenario 1:
{
//..
// ..
method(); //Exception handled inside the method
//..
//..
}
In this case the exception should be handled within the method() itself.
Also consider this:
Scenario 2:
{
//..
//..
try{
method(); //Exception not handled with-in the method
}
catch(){}
//..
// ..
}
Why a situation like scenario 2 is not allowed? ie why it is forced that the exception should be handled within the method?
You can add throws clause to your method and make it throw an exception, which can be handled, as mentioned in Situation 2. So its allowed, like this:-
void method() throws Exception{
}
Both scenarios are allowed. The restriction (if that's the right term) that Java imposes is that the exception must be handled somewhere.
In the first scenario, the called method handles the exception itself - so there's no need for the try-catch in the calling method.
The second scenario is valid - but only if method() includes the throws declaration to indicate that the exception must be handled somewhere else.
void method() throws Exception
{
}
It is allowed!
use as follows
public void method() throws ClassNotFoundException {
to catch a ClassNotFoundException.
(In most cases you should not throw a bare Exception, like other posters simplified)
Whether to chatch inside or outside is software design. There is no rule of thumb.
My experience is that catching outside leads to less complex code, which can be better unit tested .
Look for design pattern "last line of defense":
That means that in your top most class e.g in main() there is a catch (Exception ex) {
which catches when no other method catched it. in that case you can log the exception and (try to) safely shut down your system. This is the last line of defense.
Note: spmetimes it also makes sense to catch(Throweable th),
If you handle exception using senario-2, then cannot map the exception to the actual one. i.e you cannot state it as per the code in block. So please handle the exception to the spot itself, so that you can specifically explain why the exception has occurred.
As said above, the idea is to throw early and catch late. Overall, you want to minimize exceptions you throw by simply making your logic "flow". But there are always situations which are tricky to handle, or obfuscate code too much, so it is worth ensuring the user understands the risks of using certain methods and handles them accordingly.
TL;DR: Never trap InterruptedException unless you really mean to. It almost always needs to be thrown.
This great question is actually a very important design decision. Getting this right is difficult and getting this right across an entire team is even more difficult. The answer to the question lies within your implementation. Does the error need to be immediately shown to the user? Do you have an auxiliary method to recover from the failure? Is the exception a fatal event?
Please do yourself a favor and never write an empty exception handler. You will be very happy to have put in a log.debug statement in there when things go awry. Other than that: learn what every exception means and respond to it in the most graceful way possible.

Should I return null or throw an exception?

I found questions here Should a retrieval method return 'null' or throw an exception when it can't produce the return value? and Should functions return null or an empty object?, but I think my case is quite different.
I'm writing an application that consists of a webservice and a client. The webservice is responsible to access data, and return data to the client. I design my app like this:
//webservice
try
{
DataTable data = GetSomeData(parameter);
return data
}
catch (OopsException ex)
{
//write some log here
return null;
}
//client:
DataTable data = CallGetSomeData(parameter);
if(data == null)
{
MessageBox.Show("Oops Exception!");
return;
}
Well, there is a rule of not returning null. I don't think that I should just rethrow an exception and let the client catch SoapException. What's your comment? Is there better approach to solve this problem?
Thank you.
In your case, an exception has already been thrown and handled in some manner in your web service.
Returning null there is a good idea because the client code can know that something errored out in your web service.
In the case of the client, I think the way you have it is good. I don't think there is a reason to throw another exception (even though you aren't in the web service anymore).
I say this, because, technically, nothing has caused an error in your client code. You are just getting bad data from the web service. This is just a matter of handling potentially bad input from an outside source.
Personally, as a rule of thumb, I shy away from throwing exceptions when I get bad data since the client code can't control that.
Just make sure you handle the data == null condition in such a way that it doesn't crash your client code.
In general i try to design my webservices in such way that they return a flag of some sort that indicates whether there was a technical/functional error or not.
additionally i try to return a complex object for result not just a string, so that i can return things like:
result->Code = "MAINTENANCE"
result->MaintenanceTill = "2010-10-29 14:00:00"
so for a webservice that should get me a list of dataEntities i will return something like:
<result>
<result>
<Code>OK</Code>
</result>
<functionalResult>
<dataList>
<dataEntity>A</dataEntity>
</dataList>
</functionalResult>
</result>
so every failure that can occur behind my webservice is hidden in a error result.
the only exceptions that developers must care about while calling my webservice are the exceptions or errors that can occur before the webservice.
All the WebServices that I've used return objects, not simple data types. These objects usually contain a bool value named Success that lets you test very quickly whether or not to trust the data returned. In either event, I think any errors thrown should be untrappable (i.e. unintentional) and therefore signify a problem with the service itself.
I think there may be a few factors to consider when making a decision:
what is the idiomatic way to do this in the language your using (if it wasn't a webservice)
how good your soap/webservice library is (does it propogate exceptions or no)
what's the easiest thing for the client to do
I tend to make the client do the easiest, idiomatic thing, within the limitations of the library. If the client lib doesn't take care of auto restoring serialized exceptions I would probably wrap it with a lib that did so I could do the following.
Client:
try:
# Restore Serialized object, rethrow if exception
return CallGetSomeData(parameter);
except Timeout, e:
MessageBox.Show("timed out")
except Exception, e:
MessageBox.Show("Unknown error")
exit(1)
WebService:
try:
return GetSomeData(parameter) # Serialized
except Exception, e:
return e # Serialized
Your first problem is "a rule of not returning null". I would strongly suggest reconsidering that.
Returning a SoapException is a possibility, but like hacktick already mentioned, it would be better to return a complex object with a status flag {Success,Fail} with every response from the web service.
I think it all boils down to the question whether or not your client can use any info as to why no data was returned.
For example - if no data was returned because the (say sql) server that is called in GetSomeData was down, and the client can actually do something with that information (e.g. display an appropriate message) - you don't want to hide that information - throwing an error is more informative.
Another example - if parameter is null, and that causes an exception.. (although you probably should have taken care of that earlier in the code.. But you get the idea) - should have throw an appropriate (informative) exception.
If the client doesn't care at all why he didn't get any data back, you may return null, he'll ignore the error text anyhow and he's code will look the same..
If your client and service are running on different machines or different processes, it will be impossible to throw an error from the service and catch it on the client. If you insist on using exceptions, the best you can hope for is some proxy on the client to detect the error condition (either null or some other convention) and re-throw a new exception.
The general practice in handling exception is, when the sequence of flow is expected in the normal circumstance where as the sequence could not be completed due to non-availability of resources or expected input.
In your case, you still need to decide how do you want your client side code to react for null or exception.
How about passing in a delegate to be invoked when anything bad happens? The delegate could throw an exception if that's what the outside could would like, or let the function return null (if the outside code will check for that), or possibly take some other action. Depending upon the information passed to the delegate, it may be able to deal with problem conditions in such a way as to allow processing to continue (e.g. the delegate might set a 'retry' flag the first few times it's called, in case flaky network connections are expected). It may also be possible for a delegate to log information that wouldn't exist by the time an exception could get caught.
PS--It's probably best to pass a custom class to the problem-detected delegate. Doing that will allow for future versions of the method to provide additional information to the delegate, without breaking any implementations that expect the simpler information.
Exceptions are recommended in the same process space. Across processes, it is only through information that a success/failure is evaluated.
Since you are the client to your webservice, you can log the exception at the service layer and return null to the client, yet the client should still know if the CallGetSomeData returned null because a) data is not available, or b) there is a database exception as the table is locked. Hence its always good to know what has caused the error for easier reporting at client side. You should have a error code and description as part of your message.
If you are not consuming your webservice then you should definetly throw exception for the same reasons mentioned above, client should know what has happened and its upto them to decide to what to do with that.

What is the suggested way to show exception messages on UI which were produced in Business Layer?

Is there a pattern OR 'a best practice' on creating user's friendly messages in the presentation layer by using exceptions which were thrown from the Business Layer?
Actually in many cases I prefer to throw Application Exceptions and this is forcing me to catch them on UI (aspx.cs pages). And if the process is complex which may produce many different types of exceptions I have to have many catch blocks to produce specific error messages.
Is there a better way coming to your mind? A pattern maybe for similar cases?
thanks
First: I think it is best practice only to catch exceptions in code I can handle at this time. If I cannot handle just let it promote to higher level.
Second: There is a possibility to catch exceptions globally:
public static void RegisterExceptionHandler()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler (Application_UIThreadException);
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
In this exception handling methods all exceptions that have not been handled are catched. Here you can notify the user that something "unexpected" has happend.
You could use a custom exception class to return errors via exception to the UI layer. These custom exceptions could then contain an error message that will be meaningful to the user, so you can display that just like you would any other error message.
That way you will only need a single exception handler in the UI, instead of many for each type of error...

Why are empty catch blocks a bad idea? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I've just seen a question on try-catch, which people (including Jon Skeet) say empty catch blocks are a really bad idea? Why this? Is there no situation where an empty catch is not a wrong design decision?
I mean, for instance, sometimes you want to get some additional info from somewhere (webservice, database) and you really don't care if you'll get this info or not. So you try to get it, and if anything happens, that's ok, I'll just add a "catch (Exception ignored) {}" and that's all
Usually empty try-catch is a bad idea because you are silently swallowing an error condition and then continuing execution. Occasionally this may be the right thing to do, but often it's a sign that a developer saw an exception, didn't know what to do about it, and so used an empty catch to silence the problem.
It's the programming equivalent of putting black tape over an engine warning light.
I believe that how you deal with exceptions depends on what layer of the software you are working in: Exceptions in the Rainforest.
They're a bad idea in general because it's a truly rare condition where a failure (exceptional condition, more generically) is properly met with NO response whatsoever. On top of that, empty catch blocks are a common tool used by people who use the exception engine for error checking that they should be doing preemptively.
To say that it's always bad is untrue...that's true of very little. There can be circumstances where either you don't care that there was an error or that the presence of the error somehow indicates that you can't do anything about it anyway (for example, when writing a previous error to a text log file and you get an IOException, meaning that you couldn't write out the new error anyway).
I wouldn't stretch things as far as to say that who uses empty catch blocks is a bad programmer and doesn't know what he is doing...
I use empty catch blocks if necessary. Sometimes programmer of library I'm consuming doesn't know what he is doing and throws exceptions even in situations when nobody needs it.
For example, consider some http server library, I couldn't care less if server throws exception because client has disconnected and index.html couldn't be sent.
Exceptions should only be thrown if there is truly an exception - something happening beyond the norm. An empty catch block basically says "something bad is happening, but I just don't care". This is a bad idea.
If you don't want to handle the exception, let it propagate upwards until it reaches some code that can handle it. If nothing can handle the exception, it should take the application down.
I think it's okay if you catch a particular exception type of which you know it's only going to be raised for one particular reason, and you expect that exception and really don't need to do anything about it.
But even in that case, a debug message might be in order.
There are rare instances where it can be justified. In Python you often see this kind of construction:
try:
result = foo()
except ValueError:
result = None
So it might be OK (depending on your application) to do:
result = bar()
if result == None:
try:
result = foo()
except ValueError:
pass # Python pass is equivalent to { } in curly-brace languages
# Now result == None if bar() returned None *and* foo() failed
In a recent .NET project, I had to write code to enumerate plugin DLLs to find classes that implement a certain interface. The relevant bit of code (in VB.NET, sorry) is:
For Each dllFile As String In dllFiles
Try
' Try to load the DLL as a .NET Assembly
Dim dll As Assembly = Assembly.LoadFile(dllFile)
' Loop through the classes in the DLL
For Each cls As Type In dll.GetExportedTypes()
' Does this class implement the interface?
If interfaceType.IsAssignableFrom(cls) Then
' ... more code here ...
End If
Next
Catch ex As Exception
' Unable to load the Assembly or enumerate types -- just ignore
End Try
Next
Although even in this case, I'd admit that logging the failure somewhere would probably be an improvement.
Per Josh Bloch - Item 65: Don't ignore Exceptions of Effective Java:
An empty catch block defeats the purpose of exceptions
At the very least, the catch block should contain a comment explaining why it is appropriate to ignore the exception.
Empty catch blocks are usually put in because the coder doesn't really know what they are doing. At my organization, an empty catch block must include a comment as to why doing nothing with the exception is a good idea.
On a related note, most people don't know that a try{} block can be followed with either a catch{} or a finally{}, only one is required.
An empty catch block is essentially saying "I don't want to know what errors are thrown, I'm just going to ignore them."
It's similar to VB6's On Error Resume Next, except that anything in the try block after the exception is thrown will be skipped.
Which doesn't help when something then breaks.
This goes hand-in-hand with, "Don't use exceptions to control program flow.", and, "Only use exceptions for exceptional circumstances." If these are done, then exceptions should only be occurring when there's a problem. And if there's a problem, you don't want to fail silently. In the rare anomalies where it's not necessary to handle the problem you should at least log the exception, just in case the anomaly becomes no longer an anomaly. The only thing worse than failing is failing silently.
Empty catch blocks are an indication of a programmer not knowing what to do with an exception. They are suppressing the exception from possibly bubbling up and being handled correctly by another try block. Always try and do something with the exception you are catching.
I think a completely empty catch block is a bad idea because there is no way to infer that ignoring the exception was the intended behavior of the code. It is not necessarily bad to swallow an exception and return false or null or some other value in some cases. The .net framework has many "try" methods that behave this way. As a rule of thumb if you swallow an exception, add a comment and a log statement if the application supports logging.
If you dont know what to do in catch block, you can just log this exception, but dont leave it blank.
try
{
string a = "125";
int b = int.Parse(a);
}
catch (Exception ex)
{
Log.LogError(ex);
}
Because if an exception is thrown you won't ever see it - failing silently is the worst possible option - you'll get erroneous behavior and no idea to look where it's happening. At least put a log message there! Even if it's something that 'can never happen'!
I find the most annoying with empty catch statements is when some other programmer did it. What I mean is when you need to debug code from somebody else any empty catch statements makes such an undertaking more difficult then it need to be. IMHO catch statements should always show some kind of error message - even if the error is not handled it should at least detect it (alt. on only in debug mode)
It's probably never the right thing because you're silently passing every possible exception. If there's a specific exception you're expecting, then you should test for it, rethrow if it's not your exception.
try
{
// Do some processing.
}
catch (FileNotFound fnf)
{
HandleFileNotFound(fnf);
}
catch (Exception e)
{
if (!IsGenericButExpected(e))
throw;
}
public bool IsGenericButExpected(Exception exception)
{
var expected = false;
if (exception.Message == "some expected message")
{
// Handle gracefully ... ie. log or something.
expected = true;
}
return expected;
}
Generally, you should only catch the exceptions you can actually handle. That means be as specific as possible when catching exceptions. Catching all exceptions is rarely a good idea and ignoring all exceptions is almost always a very bad idea.
I can only think of a few instances where an empty catch block has some meaningful purpose. If whatever specific exception, you are catching is "handled" by just reattempting the action there would be no need to do anything in the catch block. However, it would still be a good idea to log the fact that the exception occurred.
Another example: CLR 2.0 changed the way unhandled exceptions on the finalizer thread are treated. Prior to 2.0 the process was allowed to survive this scenario. In the current CLR the process is terminated in case of an unhandled exception on the finalizer thread.
Keep in mind that you should only implement a finalizer if you really need one and even then you should do a little as possible in the finalizer. But if whatever work your finalizer must do could throw an exception, you need to pick between the lesser of two evils. Do you want to shut down the application due to the unhandled exception? Or do you want to proceed in a more or less undefined state? At least in theory the latter may be the lesser of two evils in some cases. In those case the empty catch block would prevent the process from being terminated.
I mean, for instance, sometimes you want to get some additional info from somewhere (webservice, database) and you really don't care if you'll get this info or not. So you try to get it, and if anything happens, that's ok, I'll just add a "catch (Exception ignored) {}" and that's all
So, going with your example, it's a bad idea in that case because you're catching and ignoring all exceptions. If you were catching only EInfoFromIrrelevantSourceNotAvailable and ignoring it, that would be fine, but you're not. You're also ignoring ENetworkIsDown, which may or may not be important. You're ignoring ENetworkCardHasMelted and EFPUHasDecidedThatOnePlusOneIsSeventeen, which are almost certainly important.
An empty catch block is not an issue if it's set up to only catch (and ignore) exceptions of certain types which you know to be unimportant. The situations in which it's a good idea to suppress and silently ignore all exceptions, without stopping to examine them first to see whether they're expected/normal/irrelevant or not, are exceedingly rare.
There are situations where you might use them, but they should be very infrequent. Situations where I might use one include:
exception logging; depending on context you might want an unhandled exception or message posted instead.
looping technical situations, like rendering or sound processing or a listbox callback, where the behaviour itself will demonstrate the problem, throwing an exception will just get in the way, and logging the exception will probably just result in 1000's of "failed to XXX" messages.
programs that cannot fail, although they should still at least be logging something.
for most winforms applications, I have found that it suffices to have a single try statement for every user input. I use the following methods: (AlertBox is just a quick MessageBox.Show wrapper)
public static bool TryAction(Action pAction)
{
try { pAction(); return true; }
catch (Exception exception)
{
LogException(exception);
return false;
}
}
public static bool TryActionQuietly(Action pAction)
{
try { pAction(); return true; }
catch(Exception exception)
{
LogExceptionQuietly(exception);
return false;
}
}
public static void LogException(Exception pException)
{
try
{
AlertBox(pException, true);
LogExceptionQuietly(pException);
}
catch { }
}
public static void LogExceptionQuietly(Exception pException)
{
try { Debug.WriteLine("Exception: {0}", pException.Message); } catch { }
}
Then every event handler can do something like:
private void mCloseToolStripMenuItem_Click(object pSender, EventArgs pEventArgs)
{
EditorDefines.TryAction(Dispose);
}
or
private void MainForm_Paint(object pSender, PaintEventArgs pEventArgs)
{
EditorDefines.TryActionQuietly(() => Render(pEventArgs));
}
Theoretically, you could have TryActionSilently, which might be better for rendering calls so that an exception doesn't generate an endless amount of messages.
You should never have an empty catch block. It is like hiding a mistake you know about. At the very least you should write out an exception to a log file to review later if you are pressed for time.