If-statement: Best way to handle layering with same condition - c#

I'm pretty new to programming, but I've been trying to make sure I learn good design practices. My question is related to how to handle this sort of if-statement situation, as it seems to violate Don't Repeat Yourself.
I have a class with a constructor that includes a method to connect to a database. The method will write to a string if there was an error in the connection code block. I then have a process method that analyzes metadata of the database, and will also write errors if any are found. I don't want the metadata analysis to run if there was already an error in the connection method, but is this the best way to do this?:
public bool Process()
{
if (ErrorLog == null)
{
//Metadata analysis code that may write errors
if (ErrorLog == null)
return true;
else
PublishErrorLog();
return false;
}
else
PublishErrorLog();
return false;
}

You final function could look as simple as this:
public bool Process()
{
if (hasError())
return false;
//Metadata analysis code that may write errors
//Note that error log may change here
return !hasError(); //updated by juharr
}
Explanation:
The code you present may not be exactly same condition if the line with //metadata analysis could actually change the state of ErrorLog.
Simplification Step 1: Single If-Else Loop
Seeing your nested loop however, I would rather make the codes become easier to handle and to read by doing something like this
public bool Process()
{
if (ErrorLog != null){
PublishErrorLog();
return false;
}
//Metadata analysis code that may write errors
//Note that error log may change here
if (ErrorLog != null){
PublishErrorLog();
return false;
}
return true;
}
Basically, rather than making nested if-else, you make simple statement which can be returned first. Then you return if it is satisfied, else you continue.
This way, your code become single conditional loop - no nested loop.
Simplification Step 2: Error Log + Has Error Combined Function
You could further improve the code above still, given that your error logging pattern is the same, you could create function like this
bool hasError(){
if (ErrorLog != null){
PublishErrorLog();
return true;
}
return false; //no error, can continue
}
Final Code
Then the Process function would look like
public bool Process()
{
if (hasError())
return false;
//Metadata analysis code that may write errors
//Note that error log may change here
return !hasError(); //updated by juharr
}
Very concise. And you can repeat the pattern elsewhere too.

The other answers are valid. But to me this looks like a perfect case for using Exceptions. Anytime you would write to ErrorLog also throw an exception. Then you can have exactly one block at the top that handles the error.
public bool Process()
{
if (ErrorLog != null)
//At this point, the PublishErrorLog should have already been called.
return false;
try
{
// Do Metadata analysis that may throw errors
}
catch (ErrorLogException e)
{
PublishErrorLog()
return false;
}
return true;
}
This has the advantage that the metadata analysis can be as complicated and nested as you need. It just needs to throw the exception.
EDIT:
As pointed out by Aron, this can be done without having ErrorLog as a class member at all. The log information can be stored in the exception itself. The catch block could look like:
catch (ErrorLogException e)
{
var logMessage = e.logMessage;
PublishErrorLog(logMessage);
return false;
}

It seems that you are using your ErrorLog property to signal the validity of your connection. If the ErrorLog is a string, as I understand from your question, I would have a specific way to tell if the connection is valid or not, and don't rely on the nullity of the log.
e.g.
public bool Process()
{
if (HasValidConnection)
{
//Metadata analysis code that may write errors
}
if (ErrorLog == null)
{
// no errors establishing the connection neither processing metadata
return true;
}
else
PublishErrorLog();
return false;
}

Related

Exception handling design from class libarary

I'm looking for some program design guidance.
I have a class library that handles data in a database. I have a winforms app that is the presentation layer for the user to input and manage data. Say for example the user inputs some data and attempts to save it. From the winforms app I do something like:
MyTool theTool = new MyTool();
MyTool.FirstName = this.Textbox1.Text;
MyTool.LastName = this.Textbox2.Text;
//etc...
int result = MyTool.SaveData(); //result is the ID of the inserted record.
MyTool is a type in my class library. Within this type I would have:
public int SaveData()
{
if (IsReadyForInput())
{
//..open a DB connection and save out the data
//..get the ID of the saved record
}
else
{
throw new ArgumentException("One or more arguments prevented saving the data");
}
return theID
}
private bool IsReadyForInput()
{
if (this.FirstName.Length == 0)
{ return false; }
if (this.LastName.Length == 0)
{return false;}
return true;
}
Now, what I'm interested in is the best design on how exception handling should work. For example the above method is not specific at all so the user doesn't know what's wrong. So I could rewrite this to do something like:
public void SaveData()
{
string errMess = IsReadyForInput();
if (errMess.Length == 0)
{
//..open a DB connection and save out the data
//..get the ID of the saved record
}
else {
throw new ArgumentException(errMess);
}
return theID
}
private string IsReadyForInput()
{
if (this.FirstName.Length == 0)
{ return "Specify a first name"; }
if (this.LastName.Length == 0)
{return "Specify a last name";}
return true;
}
However it just doesn't seem a very elegant (or fast) method to be comparing string lengths to find an error message. I had tried writing something like:
public void SaveData()
{
ValidateInput();
//..open a DB connection and save out the data
return theID
}
private void ValidateInput()
{
if (this.FirstName.Length == 0)
{ throw new ArgumentException("Specify a first name"; }
if (this.LastName.Length == 0)
{throw new ArgumentException("Specify a first name"; }
}
The problem with this is that the exception is actually thrown by ValidateInput when the front end is calling "SaveData", so when the exception reaches the top, to me, it would seem less clear (especially if there are multiple ways of calling "ValidateInput()" from within MyTool).
Additionally I am not sure what the best way to handle the exception on the front end would be because, if an error is thrown, the ID is never returned.
I guess I am just looking for some guidance on how to handle this situation and validation/error handling in general. Thanks for any help.
The first thing I wonder about is whether you need to throw an exception at all when ordinary control flow might be enough:
if (IsReadyForInput())
{
//..open a DB connection and save out the data
//..get the ID of the saved record
}
else
{
//..do whatever you need in case of invalid input
}
The obvious problem with this suggestion is that we are in a method somewhere in your class library, and some of the desired effects (displaying warnings to the user, etc.) happen in the WinForms layer. That, however, suggests a better solution; namely, to do the validation in the WinForms code:
if (IsReadyForInput())
{
int result = theTool.SaveData();
//...and whatever else should happen.
}
else
{
//..do whatever you need in case of invalid input
}
The above approach is simpler and makes the parts of your program less dependent on each other (as MyTool doesn't need to care about validation of user input) when compared to, e.g., throwing an exception or using special return values to signal failure.
Take a look at FluentValidation (http://fluentvalidation.codeplex.com/). I think it's what you're looking for.
With it you can define your validation rules and call its validation methods. It will return a full list of potential validation errors without causing exceptions to be thrown in your code.

Why must a return statement precede a throw statement in a catch block?

The code below will complain
try
{
session.Save(obj);
return true;
}
catch (Exception e)
{
throw e;
return false; // this will be flagged as unreachable code
}
whereas this will not:
try
{
session.Save(obj);
return true;
}
catch (Exception e)
{
return false;
throw e;
}
I dont get it...I thought my csc101 told me that return statements should always be the last statement in a function and that it exits the function and return control to the calling code. Why does this defy my professor's logic, and why does only one of these generate a warning?
return will exit the method; throw will also exit the method, assuming it is not inside the try. It can only exit once!
So regardless of the order - the first of the throw / return effectively end the method.
As more general feedback, though: if the intent is to return false upon failure, all you need is:
try
{
session.Save(obj);
return true;
}
catch
{
return false;
}
Personally, I would say that this is bad code - it hides the actual problem from the caller, making it very hard to debug. It tells us nothing of why it failed. I would say that the better approach is simply to let the exception bubble. In that case, there is no point returning true, because we would never return false - and there is no point catching an exception just to re-throw it. So the entire method becomes:
session.Save(obj);
(nothing else required whatsoever)
If your question is "why does only one of these generate a warning": a fair question, but the compiler isn't required to spot either of them for you. Perhaps it should spot it. I suspect that gmcs would spot this and warn about it - the compiler in mono is far more willing to point out stupidity.
Edit: as expected, [g]mcs outputs:
Program.cs(15,13): warning CS0162: Unreachable code detected
Program.cs(28,13): warning CS0162: Unreachable code detected
for the code below - so it does indeed report both uses as warnings:
class Program
{
static void Main() { }
static void DoSomething() { }
bool ReturnFirst()
{
try
{
DoSomething();
return true;
}
catch
{
return false;
throw; // line 15
}
}
bool ThrowFirst()
{
try
{
DoSomething();
return true;
}
catch
{
throw;
return false; // line 28
}
}
}
You are wrong: both your examples raise the Dead code compiler error because both throw and return mark the exit point of a method and no further code is allowed beyond that point.
However, whether the compiler allows it or not, the code below either the throw or the return is still dead and will never get a chance to execute.
(NOTE: this question was initially tagged as Java and my first sentence pertains to Java compiler semantics)
Because any code after the return statement within a code block will be unreachable.
This answer is based on C# and may or may not be applicable to Java.
In this case, you do not actually need the return statement. throw will be the last step of the function.
In this example, both return and throw will end the current function. Regardless of which way around you put them, then first will always prevent the second from being reachable.
NOTE: The exception to when a throw statement would end the function is if it was to be wrapped in a try block. In this case, the throw function would end execution of the remaining try block code, and move to the most relevant catch block - or finally block if a catch is not applicable.
Your code should look like this:
try
{
session.Save(obj);
return true;
}
catch(Exception e)
{
throw e;
}
However, there is not much point in having the try/catch anyway if all you are doing is re-throwing the exception.
To specifically answer your only question:
Why does this defiles my professor's logic?
Well either your professor is wrong, or you have misunderstood them
The "return false;" in the catch block is unreachable because of the "throw e;" just before it. When the code executes in the catch block the first line is a throw which means you immediately throw the exception to the calling method and therefore any following code does not get executed.
try
{
session.Save(obj);
return true;
}
catch(Exception e)
{
throw e; //Throws exception to calling method
return false; //this will be flagged as unreachable code
}
I hope this helps.

Return from a Class Execution using an Event or ..?

I'm going to provide a simple example of what I'm trying to do -- hopefully it is possible?
I basically have a class that does a whole ton of formatting/analyzing to the data. As a result, there a lot of things that can go wrong with this. The problem I have is handling the class when things go wrong. I want all execution of this class to stop once an error has occurred.
This class (AnalyzingStuff) is called from a parent form that does various things based on the result of this classes execution.
Ideally, I would fire an event named say "ABORT".
So in this code here I do the following:
Class AnalyzingStuff{
public event EventHandler ABORT;
public AnalyzingStuff(){
for(int i = 0; i < 999999; i ++){
AnalyzeSomeStuff();
AnalyzerSomeOtherStuff();
}
MoreStuff();
OtherStuff();
}
private void AnalyzeSomeStuff(){
if(someconditionNotMet){
//EXIT OUT OF THIS CLASS, STOP EXECUTION!!!
this.ABORT.Invoke(this, null);
}
}
}
Calling this 'ABORT' event, I would stop the execution of this class (stop the loop and not do anything else). I could also catch this event handler in some other parent form. Unfortunately, I can't find any way of stopping the execution of this class.
Ideas so far:
The obvious answer is to simply set a flag and constantly check this flag over and over in multiple places, but I really don't like this approach (my current implementation). Having to check this after every single method call (there are MANY) is ugly codewise.
I thought maybe a background worker or something where you could cancel the execution of the DoWork?
Use a form as a base class for the AnalyzingStuff so I can simply call "this.Close();".
What do you think is the best approach to this situation? Are these the best solutions? Are there any other elegant solutions to what I want here or am I going completely in the wrong direction?
EDIT: I have a series of try/catch blocks used throughout this code that is used to handle different errors that can occur. Unfortunately, not all of them call for an Abort to occur so they need to be caught immediately. Therefore, try/catch not the most ideal approach.. or is it?
Don't do analysys in the constructor. Do it in a main Analyze() method.
Use exceptions. If you want to abort because of a fatal error, throw a fatal exception. That is, throw an exception that you don't catch within the scope of the main analysis method.
class Analyzer
{
public Analyzer()
{
// initialize things
}
public void Analyze()
{
// never catch a fatal exception here
try
{
AnalyzeStuff();
... optionally call more methods here ...
}
catch (NonFatalException e)
{
// handle non fatal exception
}
... optionally call more methods (wrapped in try..catch) here ...
}
private void AnalyzeStuff()
{
// do stuff
if (something nonfatal happens)
throw new NonFatalException();
if (something fatal happens)
throw new FatalException();
}
}
outside:
{
var analyzer = new Analyzer();
try
{
analyzer.Analyze();
}
catch (FatalException)
{
Console.WriteLine("Analysis failed");
}
}
If you don't like using exception this way, you can accomplish the same thing by having every analysis method return a bool:
if (!AnalyzeStuff())
return false;
if (!AnalyzeMoreStuff())
return false;
...
return true;
But you end up with a lot of return statements or a lot of braces. It's a matter of style and preference.
Could you throw an Exception if things go wrong, and run a try catch around where you call the method in the loop?
if you do this you could do stuff if the class fails (which you will put in the catch), and stuff you could do to close connections to database ++ when it is done.
or you could make the methods return an int, to tell if the execution of the method was valid. ex. return 0; is valid execution, return 1-500 would then might be different error codes. Or you might go for the simple version of passing a bool. If you need to return values from methods other than the error code you could pass these as OUT variables. example following:
Class AnalyzingStuff{
public AnalyzingStuff(){
for(int i = 0; i < 999999; i ++){
if (!AnalyzeSomeStuff() || !AnalyzerSomeOtherStuff())
break;
}
MoreStuff();
OtherStuff();
}
private bool AnalyzeSomeStuff(){
if(someconditionNotMet){
return false;
}
return true;
}
}
You can of course use your event. I just removed it for the simplicity of it.

Using a Goto to enhance the DRY principle and code clarity: a good idea?

I have some code that is structured like the following:
if (someStatement)
{
//...
if (SomeOtherStatement)
{
//..., possibly more cases like this
}
else
{
//goto warning;
//would otherwise repeat
//the MessageBox.Show here
}
}
else
{
//goto warning;
}
//...
warning:
MessageBox.Show("some warning");
As i abhor copying code, is this one of the few useful applications of goto or is there a better structure i can use?
What about this?
if (someStatement)
{
//...
if (SomeOtherStatement)
{
//..., possibly more cases like this
return; // in the inner-most case
}
}
MessageBox.Show("some warning");
Yes, but only if by goto you mean "create a function and call it multiple times".
the best approach depends on what the rest of your code looks like. if the code shown is the last code in that method:
if(someStatement) {
// ...
if(SomeOtherStatement)
{
// a couple of lines of code
return; // !
}
}
MessageBox.Show("someWarning");
if not, you probably have to retort to something like this:
if(someStatement) {
// ...
if(SomeOtherStatement)
{
// a couple of lines of code
}
else
{
showWarning("not someOtherStatement");
}
}
else
{
showWarning("not someStatement");
}
I personally consider centralized error handling as "almost the only case" where goto is acceptable. However, for a better structure, I would put the label fully outside of the else, at the very end of your function.
Are you displaying the same error message on both lines? Then you should write a function that calls just that line and call that function on both occasions.
if (someStatement)
{
//...
if (SomeOtherStatement)
{
//..., possibly more cases like this
}
else
{
showError();
}
}
else
{
showError();
}
BTW: this is a bad example, it can be solved with a single else-branch catching the error. Here is a better one:
if (!doSomething())
{
showError();
}
doSomethingElse();
if (!anotherCall())
{
showError();
}
If you are going to get into a deep nasty error testing statement like you have, then you might want to consider wrapping it with a single try/catch, and throw the appropriate application specific exceptions from within the if statement, and catch those specific exceptions in the catch block, letting all the others go to be caught further up the chain.
Exceptions are the proper way to handle errors in .NET, throw them, but use them wisely:
try
{
if (someStatement)
{
//...
if (SomeOtherStatement)
{
//..., possibly more cases like this
}
else
{
throw new MyException();
//would otherwise repeat
//the MessageBox.Show here
}
}
}
catch(MyException e)
{
MessageBox.Show(e.Message);
// log the exception, if necessary
}
finally
{
// tidy up
}
With the exception you get a strongly typed answer to what went wrong which you can easily implement into logging systems.
Since (starting with FrameWork 1.1) logical-and "&&" : "only evaluates its second operand if necessary."
What's wrong with :
if(someStatement && someOtherStatement)
{
// more whatever
}
else
{
// raise an exception, call a method, show messagebox, whatever
}
Depending on the complexity of logical evaluation going on if the first clause evaluates to true : and you, possibly, implement lots of other tests, any number of which could result in errors : all of which you want handled in the identical way : I'd consider it mandatory to either raise a specific exception, call a method to handle the error, or put the whole thing in a try-catch block (which can be quite ugly if there's a lot of code).
A low-down-dirty-sneaky method I would use if it was a reasonable presumption that the possibility of error was quite remote 99% of the time the code was called : I'd set a boolean flag to reflect an error state : evaluate it on completion of the complex code block, and do what needed to be done : of course if your code branches off somewhere as a result of these internal evaluations : that would not be a good thing.
I think goto is a bad idea. If you have to jump, throw an exception, as proposed by joshcomley; if you just want to output the warning message, but continue without a jump, call a method.

Additional try statement in catch statement - code smell?

Situation:
My application need to process the first step in the business rules (the initial try-catch statement). If an certain error occurs when the process calls the helper method during the step, I need to switch to a second process in the catch statement. The back up process uses the same helper method. If an same error occurs during the second process, I need to stop the entire process and throw the exception.
Implementation:
I was going to insert another try-catch statement into the catch statement of the first try-catch statement.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
HelperMethod(s1);
}
catch(Exception e1)
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
//try catch statement for second process.
try
{
HelperMethod(s2);
}
catch(Exception e2)
{
throw e2;
}
}
What would be the correct design pattern to avoid code smells in this implementation?
I caused some confusion and left out that when the first process fails and switches to the second process, it will send different information to the helper method. I have updated the scenario to reflect the entire process.
If the HelperMethod needs a second try, there is nothing directly wrong with this, but your code in the catch tries to do way too much, and it destroys the stacktrace from e2.
You only need:
try
{
//call helper method
HelperMethod();
}
catch(Exception e1)
{
// maybe log e1, it is getting lost here
HelperMethod();
}
I wouldn't say it is bad, although I'd almost certainly refactor the second block of code into a second method, so keep it comprehensible. And probably catch something more specific than Exception. A second try is sometimes necessary, especially for things like Dispose() implementations that might themselves throw (WCF, I'm looking at you).
The general idea putting a try-catch inside the catch of a parent try-catch doesn't seem like a code-smell to me. I can think of other legitimate reasons for doing this - for instance, when cleaning up an operation that failed where you do not want to ever throw another error (such as if the clean-up operation also fails). Your implementation, however, raises two questions for me: 1) Wim's comment, and 2) do you really want to entirely disregard why the operation originally failed (the e1 Exception)? Whether the second process succeeds or fails, your code does nothing with the original exception.
Generally speaking, this isn't a problem, and it isn't a code smell that I know of.
With that said, you may want to look at handling the error within your first helper method instead of just throwing it (and, thus, handling the call to the second helper method in there). That's only if it makes sense, but it is a possible change.
Yes, a more general pattern is have the basic method include an overload that accepts an int attempt parameter, and then conditionally call itself recursively.
private void MyMethod (parameterList)
{ MyMethod(ParameterList, 0)l }
private void MyMethod(ParameterList, int attempt)
{
try { HelperMethod(); }
catch(SomeSpecificException)
{
if (attempt < MAXATTEMPTS)
MyMethod(ParameterList, ++attempt);
else throw;
}
}
It shouldn't be that bad. Just document clearly why you're doing it, and most DEFINITELY try catching a more specific Exception type.
If you need some retry mechanism, which it looks like, you may want to explore different techniques, looping with delays etc.
It would be a little clearer if you called a different function in the catch so that a reader doesn't think you're just retrying the same function, as is, over again. If there's state happening that's not being shown in your example, you should document it carefully, at a minimum.
You also shouldn't throw e2; like that: you should simply throw; if you're going to work with the exception you caught at all. If not, you shouldn't try/catch.
Where you do not reference e1, you should simply catch (Exception) or better still catch (YourSpecificException)
If you're doing this to try and recover from some sort of transient error, then you need to be careful about how you implement this.
For example, in an environment where you're using SQL Server Mirroring, it's possible that the server you're connected to may stop being the master mid-connection.
In that scenario, it may be valid for your application to try and reconnect, and re-execute any statements on the new master - rather than sending an error back to the caller immediately.
You need to be careful to ensure that the methods you're calling don't have their own automatic retry mechanism, and that your callers are aware there is an automatic retry built into your method. Failing to ensure this can result in scenarios where you cause a flood of retry attempts, overloading shared resources (such as Database servers).
You should also ensure you're catching exceptions specific to the transient error you're trying to retry. So, in the example I gave, SqlException, and then examining to see if the error was that the SQL connection failed because the host was no longer the master.
If you need to retry more than once, consider placing an 'automatic backoff' retry delay - the first failure is retried immediately, the second after a delay of (say) 1 second, then doubled up to a maximum of (say) 90 seconds. This should help prevent overloading resources.
I would also suggest restructuring your method so that you don't have an inner-try/catch.
For example:
bool helper_success = false;
bool automatic_retry = false;
//run initial process
try
{
//call helper method
HelperMethod();
helper_success = true;
}
catch(Exception e)
{
// check if e is a transient exception. If so, set automatic_retry = true
}
if (automatic_retry)
{ //try catch statement for second process.
try
{
HelperMethod();
}
catch(Exception e)
{
throw;
}
}
Here's another pattern:
// set up state for first attempt
if(!HelperMethod(false)) {
// set up state for second attempt
HelperMethod(true);
// no need to try catch since you're just throwing anyway
}
Here, HelperMethod is
bool HelperMethod(bool throwOnFailure)
and the return value indicates whether or not success occurred (i.e., false indicates failure and true indicates success). You could also do:
// could wrap in try/catch
HelperMethod(2, stateChanger);
where HelperMethod is
void HelperMethod(int numberOfTries, StateChanger[] stateChanger)
where numberOfTries indicates the number of times to try before throwing an exception and StateChanger[] is an array of delegates that will change the state for you between calls (i.e., stateChanger[0] is called before the first attempt, stateChanger[1] is called before the second attempt, etc.)
This last option indicates that you might have a smelly setup though. It looks like the class that is encapsulating this process is responsible for both keeping track of state (which employee to look up) as well as looking up the employee (HelperMethod). By SRP, these should be separate.
Of course, you need to a catch a more specific exception than you currently are (don't catch the base class Exception!) and you should just throw instead of throw e if you need to rethrow the exception after logging, cleanup, etc.
You could emulate C#'s TryParse method signatures:
class Program
{
static void Main(string[] args)
{
Exception ex;
Console.WriteLine("trying 'ex'");
if (TryHelper("ex", out ex))
{
Console.WriteLine("'ex' worked");
}
else
{
Console.WriteLine("'ex' failed: " + ex.Message);
Console.WriteLine("trying 'test'");
if (TryHelper("test", out ex))
{
Console.WriteLine("'test' worked");
}
else
{
Console.WriteLine("'test' failed: " + ex.Message);
throw ex;
}
}
}
private static bool TryHelper(string s, out Exception result)
{
try
{
HelperMethod(s);
result = null;
return true;
}
catch (Exception ex)
{
// log here to preserve stack trace
result = ex;
return false;
}
}
private static void HelperMethod(string s)
{
if (s.Equals("ex"))
{
throw new Exception("s can be anything except 'ex'");
}
}
}
Another way is to flatten the try/catch blocks, useful if you're using some exception-happy API:
public void Foo()
{
try
{
HelperMethod("value 1");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
try
{
HelperMethod("value 2");
return; // finished
}
catch (Exception e)
{
// possibly log exception
}
// ... more here if needed
}
An option for retry (that most people will probably flame) would be to use a goto. C# doesn't have filtered exceptions but this could be used in a similar manner.
const int MAX_RETRY = 3;
public static void DoWork()
{
//Do Something
}
public static void DoWorkWithRetry()
{
var #try = 0;
retry:
try
{
DoWork();
}
catch (Exception)
{
#try++;
if (#try < MAX_RETRY)
goto retry;
throw;
}
}
In this case you know this "exception" probably will happen so I would prefer a simple approach an leave exceptions for the unknown events.
//run initial process
try
{
//initial information used in helper method
string s1 = "value 1";
//call helper method
if(!HelperMethod(s1))
{
//backup information if first process generates an exception in the helper method
string s2 = "value 2";
if(!HelperMethod(s2))
{
return ErrorOfSomeKind;
}
}
return Ok;
}
catch(ApplicationException ex)
{
throw;
}
I know that I've done the above nested try catch recently to handle decoding data where two third party libraries throw exceptions on failure to decode (Try json decode, then try base64 decode), but my preference is to have functions return a value which can be checked.
I generally only use the throwing of exceptions to exit early and notify something up the chain about the error if it's fatal to the process.
If a function is unable to provide a meaningful response, that is not typically a fatal problem (Unlike bad input data).
It seems like the main risk in nested try catch is that you also end up catching all the other (maybe important) exceptions that might occur.

Categories

Resources