I am troubleshooting old source code, and came across a statement like this:
if (Monitor.TryEnter(lockObj))
{
try
{
//does something
if (failing_condition)
{
Monitor.Exit(lockObj);
throw new Exception("Oops!");
}
catch (Exception ex)
{
throw ex;
}
finally
{
Monitor.Exit(lockObj);
}
}
}
The code is crashing with a System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
Is there a safe way to call Monitor.Exit() on both the failing condition and when normal execution finishes?
Just do it in the finally block, its always runs even if an exception is thrown above. Also the catch section is unnecessary.
if(Monitor.TryEnter(lockObj)) {
try {
//does something
if(failing_condition) {
throw new Exception("Oops!");
}
}
finally {
Monitor.Exit(lockObj);
}
}
Related
Comparing the old way versus the new way of error handling, by using Exception filters, what is exactly the advantage for me of using filters and when should I use it? is there an scenario where I can get a good advantage of this new feature?
I have read about the unwinding stack but still I don't get the scenario where we can not handle that under the old way. Explain like I'm 5 please.
try
{
Foo.DoSomethingThatMightFail(null);
}
catch (MyException ex) when (ex.Code == 42)
{
Console.WriteLine("Error 42 occurred");
}
vs
try
{
Foo.DoSomethingThatMightFail(null);
}
catch (MyException ex)
{
if (ex.Code == 42)
Console.WriteLine("Error 42 occurred");
else
throw;
}
I know there is other version of this question, the problem is, that the question mention benefits that I cant actually find, for instance.
Exception filters are preferable to catching and rethrowing because
they leave the stack unharmed. If the exception later causes the stack
to be dumped, you can see where it originally came from, rather than
just the last place it was rethrown.
after doing some testing, I did not see the difference between both, I still see the exception from the place it was rethrown. So, or the information is not confirmed, I don't understand the Exception filters( that is why I am asking), or I am doing it wrong (also please correct me if I am wrong).
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email#domain.com";
}
then:
try
{
throw new specialException();
//throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e) when(e.code == 0)
{
WriteLine("E.code 0");
throw;
//throw e;
}
catch (FormatException e)
{
if (cond1)
{
WriteLine("cond1 " + e.GetBaseException().Message+" - "+e.StackTrace);
throw;
}
throw;
}
catch (Exception e) //when (cond2)
{
Console.WriteLine("cond2! " + e.Message);
throw;
}
I don't understand Paulo's answer. He may be correct or he may not be.
I definitely disagree with Alexander's answer. It is not just syntactic sugar. Pure syntactic sugar means it's solely an easier way of writing something, and that execution will be unchanged.
However, that's not the case in this situation. As Thomas Levesque points out in his blog, exception filters do not unwind the stack. So when debugging the program, if you have an exception thrown in your try block, with exception filters you'll be able to see what the state of the values are in the try block. If you weren't using exception filters, your code would enter the catch block and you would lose information about the state of the variables in the try block.
Note that I'm not talking about the stacktrace (it's a different but related concept to the stack). The stacktrace would be unchanged unless you explicitly did rethrow the exception as in throw exception; in a catch block where exception is the caught exception.
So while in some cases you can think of it as something that may or may not make your code cleaner (depending on your opinion of the syntax), it does change the behavior.
Exception filters have been added to C# because they were in Visual Basic and the "Roslyn" team found them useful when developing "Roslyn".
Beware that the filter runs in the context of the throw and not in the context of the catch.
Anyhow, one use might be something like this:
try
{
//...
}
catch (SqlException ex) when (ex.Number == 2)
{
// ...
}
catch (SqlException ex)
{
// ...
}
Edited:
One might think this is just syntactic sugar over this:
try
{
//...
}
catch (SqlException ex) when (ex.Number == 2)
{
// ...
}
catch (SqlException ex)
{
if (ex.Number == 2)
{
// ...
}
else
{
// ...
}
}
But if we change the code for this:
try
{
//...
}
catch (SqlException ex) when (ex.Number == 2)
{
// ...
}
It will be more like this:
try
{
//...
}
catch (SqlException ex) when (ex.Number == 2)
{
// ...
}
catch (SqlException ex)
{
if (ex.Number == 2)
{
// ...
}
else
{
throw
}
}
But there's one fundamental difference. The exception is not caught and rethrown if ex.Number is not 2. It's just not caught if ex.Number is not 2.
UPD: As pointed out in the answer by Paulo Morgado, the feature has been in CLR for quite some time and C# 6.0 only added syntax support for it. My understanding of it, however, remains as a syntactic sugar, e.g. the syntax that allows me to filter exceptions in a nicer way than it used to be, irrespective of how the previous "straightforward" method works under the hood.
=====
In my understanding, this is a syntactic sugar that allows you to more clearly define the block there your exception is going to be handled.
Consider the following code:
try
{
try
{
throw new ArgumentException() { Source = "One" };
throw new ArgumentException() { Source = "Two" };
throw new ArgumentException() { Source = "Three" };
}
catch (ArgumentException ex) when (ex.Source.StartsWith("One")) // local
{
Console.WriteLine("This error is handled locally");
}
catch (ArgumentException ex) when (ex.Source.StartsWith("Two")) // separate
{
Console.WriteLine("This error is handled locally");
}
}
catch (ArgumentException ex) // global all-catcher
{
Console.WriteLine("This error is handled globally");
}
Here you can clearly see that first and second exception are handled in the respective blocks that are separated using when safeguard, whereas the one global catch-all block will catch only the third exception. The syntax is clearer that catching all the exceptions in every block, something like:
catch (ArgumentException ex) // local
{
if (ex.Source.StartsWith("One"))
{
Console.WriteLine("This error is handled locally");
}
else
{
throw;
}
}
Debugging production code I came across something I had not seen before and am not aware of a valid purpose. In several methods of one of our controllers we have try-catch blocks. The interesting part is there are 2 throw statements in one of the catches.
Is there any reason to have 2 throw statements? If so, in what circumstance(s) does that make sense?
try
{
//statements
}
catch (SoapException se)
{
//Log statement
return null;
}
catch (Exception ex)
{
//Log statement
throw;
throw;
}
No there is no reason to throw twice. The second throw will never be reached.
It is also similar to having
public int GetNumber()
{
return 1;
return 2; // Never reached
}
Update
Resharper is a great tool to check things like this.
In this case it will grey out the second throw and tell you it is unreachable.
In the example you showed, there would be no purpose to the two throw statements. As soon as the first one is hit it starts to work its way back up the call stack until it is caught. The only way for two to make any differance is if the first one was conditional or caught before he second one was hit.
try
{
//statements
}
catch (SoapException se)
{
//Log statement
return null;
}
catch (Exception ex)
{
//Log statement
if (condition)
throw;
throw;
}
or
try
{
//statements
}
catch (SoapException se)
{
//Log statement
return null;
}
catch (Exception ex)
{
//Log statement
try
{
throw;
}
catch (Exception)
{
//Handle first thrown exception.
}
throw;
}
There is absolutely no purpose in throwing an exception twice in a row. The second throw can never be reached, and it is most likely a typo, or code that was edited, but never completed and since forgotten about.
I have a try..catch block that looks like this:
try
{
...
}
catch (IOException ioEx)
{
...
}
catch (Exception ex)
{
...
}
I'd like to handle just a certain kind of IOException, namely a sharing violation (Win32 0x20). Other IOExceptions and all other Exception descendants should be handled generally by the second catch-all catch.
Once I know that the IOException is not a sharing violation, how can I cleanly redirect the error handling flow to the general catch? If I rethrow in catch (IOException) the second catch does not invoke. I know I can nest try..catches but is there a cleaner way?
EDIT: On factoring-out handler logic
Factoring repeated code in methods will surely work, but I noticed that in general when you use factored methods for exception handling it tends to have subtle problems.
First of all, a catch clause has direct access to all of the local variables prior to the exception. But when you "outsource" exception handling to a different method then you have to pass the state to it. And when you change the code so does the handler method's signature changes, which might be a maintainability issue in more complicated scenarios.
The other problem is that program flow might be obscured. For example, if the handler method eventually rethrows the exception, the C# compiler and code analyzers like Resharper don't see it:
private void Foo()
{
string a = null;
try
{
a = Path.GetDirectoryName(a);
System.Diagnostics.Debug.Print(a);
}
catch (Exception ex)
{
HandleException(ex, a); //Note that we have to pass the "a"
System.Diagnostics.Debug.Print(
"We never get here and it's not obvious" +
"until you read and understand HandleException"
);
...!
}
}
static void HandleException(Exception ex, string a)
{
if (a != null)
System.Diagnostics.Debug.Print("[a] was not null");
throw (ex); //Rethrow so that the application-level handler catches and logs it
}
VS
private void Bar()
{
string a = null;
try
{
a = System.IO.Path.GetDirectoryName(a);
System.Diagnostics.Debug.Print(a);
}
catch (Exception ex)
{
if (a != null)
System.Diagnostics.Debug.Print("[a] was not null");
throw; //Rethrow so that the application-level handler catches and logs it
System.Diagnostics.Debug.Print(
"We never get here also, but now " +
"it's obvious and the compiler complains"
);
...!
}
}
If I want to avoid these kind of (minor) problems then it seems that there is no cleaner way than nesting try..catch blocks, as Hank pointed out.
Just factor the handling logic into a separate method.
try
{
...
}
catch (IOException ioEx)
{
if (sharing violation)
HandleSharingViolation();
else
HandleNonsharingViolation();
}
catch (Exception ex)
{
HandleNonsharingViolation();
}
Or test the exceptions yourself
catch (Exception ex)
{
if (ex is IOException && ex.IsSharingViolation()
HandleSharingViolation();
else
HandleNonsharingViolation();
}
No, you'll have to nest.
Once you are in 1 of the catch blocks, this 'try' is considered handled.
And I think it may make a lot of sense, "sharing violation" sounds like a special case that probably isn't so tightly coupled to the rest as you might be thinking. If you use nest try-catch, does the try block of the special case has to surround the exact same code? And of course it's a candidate to refactor out as a separate method.
Create Method to handle exception, pass the exception to that method , based on the type Handle the exception in the way you want.Call these method in both these blocks.
Use nested try catch blocks.
try
{
try
{
}
catch (IOException ioEx)
{
if (....)
else
throw;
}
}
catch
{
}
what about "finally"?
you can first set a 'variable' in the IOException block once you know the IOException is not sharing violation. Then, in your finally block, if that 'variable' is set, you proceed to do whatever you need to do.
Below impl. tested and confirmed.
bool booleanValue = false;
try
{
test1(); // this would thro IOException
}
catch (IOException e)
{
booleanValue = true; // whatever you need to do next
}
finally
{
if (booleanValue)
{
Console.WriteLine("Here");
}
}
Tryout this nested block
try
{
}
catch(Exception ioex)
{
try
{
}
catch(Exception ex)
{
}
}
Consider the following code where LockDevice() could possibly fail and throw an exception on ist own. What happens in C# if an exception is raised from within a finally block?
UnlockDevice();
try
{
DoSomethingWithDevice();
}
finally
{
LockDevice(); // can fail with an exception
}
Exactly the same thing that would happen if it wasn't in a finally block - an exception could propagate from that point. If you need to, you can try/catch from within the finally:
try
{
DoSomethingWithDevice();
}
finally
{
try
{
LockDevice();
}
catch (...)
{
...
}
}
The method is called Try / Catch
Where is your catch?
UnlockDevice();
try
{
DoSomethingWithDevice();
}
catch(Exception ex)
{
// Do something with the error on DoSomethingWithDevice()
}
finally
{
try
{
LockDevice(); // can fail with an exception
}
catch (Exception ex)
{
// Do something with the error on LockDevice()
}
}
Here's an interesting question. I have a system that attempts to run some initialization code. If it fails, we call the deinitializer to clean everything up.
Because we call the deinitializer in exception handling, we run the risk that both initialize and deinitialize will fail, and hypothetically, it now seems that we have to throw two exceptions.
It seems pretty unlikely that we will, though. So what happens and what should the code do here?
try { /* init code here */ }
catch (Exception ex)
{
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
throw new OCRException("Engine failed to initialize; ALSO failed to deinitialize engine!", ex2);
}
finally
{
throw new OCRException("Engine failed to initialize; failed to initialize license!", ex);
}
}
You shouldn't throw in the Finally block. Instead, use the InnerException to add information in the throw.
Update
What you have to do is to catch and rethrow with the "history" of exception, this is done with InnerException. You can edit it when bulding a new exception. This is a code snippet I just wrote to illustrate the idea that I explain in all the comments below.
static void Main(string[] args)
{
try
{
principalMethod();
}
catch (Exception e)
{
Console.WriteLine("Test : " + e.Message);
}
Console.Read();
}
public static void principalMethod()
{
try
{
throw new Exception("Primary");
}
catch (Exception ex1)
{
try
{
methodThatCanCrash();
}
catch
{
throw new Exception("Cannot deinitialize", ex1);
}
}
}
private static void methodThatCanCrash()
{
throw new NotImplementedException();
}
No need to use double throw with finalize. If you put a break point at the Console.WriteLine(...). You will notice that you have all the exception trace.
If your clean up code is failing and you cannot leave the application in a clean and known state I would let the exception go unhandled (or catch it with the UnhandledException event to log it) then close the application.
Because if you can't handle the first exception, what point is there in catching the second exception?
If I understand your problem correctly, here's what I would have done:
try { /* init code here */ }
catch (Exception ex)
{
// Passing original exception as inner exception
Exception ocrex = new OCRException("Engine failed to initialize", ex);
try
{
_DeinitializeEngine();
}
catch (Exception ex2)
{
// Passing initialization failure as inner exception
ocrex = new OCRException("Failed to deinitialize engine!", ocrex);
}
throw ocrex;
}
You have two possible exception conditions: one in which the first method failed, and one in which both methods failed.
You're already defining your own exception class. So create another (or extend the first) with a RelatedException or PriorException property. When you throw the exception in the second case, save a reference to the first exception in this property.
It's up to the exception handler that catches this exception to figure out what to do with the second exception.