Exception Handling in C#
Hello guys, sorry to disturb you all; consider the following code:
I have a question. I know that try-catch blocks are used to handle exceptions and the finally block is used to "release" any resource after the catch block has been executed. The finally block is always executed irrespective if their is an error or not.
My question is, in the above code, notice the inner try-finally statement doesn't have a catch block. So if their is an error in this try block, what happens? We noticed that their is no catch block in the inner try block, so we start looking in the outer try block? What about the finally block, we don't execute it until we finish scheming in the outer try-block? Does this mean that any catch block will always run before any finally block?
51 Replies
You're confusing the implementation details with what you actually see, I think
Don't worry about when the runtime goes looking for a catch block. What you see is that things are executed innermost-to-outermost
So if an Exception happens in that inner
try
, the finally block gets run, then the outer catchthrown exceptions "bubble" up the call stack (the methods that call method that call methods and so on)
the first fitting catch clause will be the point where execution then continues.
the finally block will always execute no matter what.
this can be a thrown exception, but it could also be a
return
statement, or simple code flow.
the order is always try->catch (if applies)->finally
and only after this the code flows like usual.
so ur step ordering is wrong.
yeah I see, like in the inner try-block, we don't have a catch, so we still executes the finally block. Then we kind of exit the inner try block and the exception is passed to outer block; if outer-block has a correct catch block, we can handle the error?
canton7
REPL Result: Success
Console Output
Compile: 412.097ms | Execution: 25.565ms | React with ❌ to remove this embed.
exactly
Yep I see, thanks guys ! will come back if I have other questions but should be good for now
Cool!
Yeah there are implementation details about when the runtime goes looking for a
catch
block, and that can lead to some odd-looking corner cases, but the bog-standard normal case, like the one in your question, behaves exactly as you'd expectStack Overflow
C# exception handling finally block before catch block
I am quite confused with how exceptions are getting thrown in C#. If an exception occurs, in the try block,
1.it gets thrown to the catch block,
2. If and only if the catch block catches it the fin...
Ah that was it,
when
clauses are executed before finally
blocksbtw, i really love how u ask questions 🙂
u explain your thoughts and assumptions, not like others that paste code and go like "whats wrong?".
so, dont start ur questions with being sorry, we are here to help 😉
Yep, seconded: very well-written question
oh yeah that as well!
$close
If you have no further questions, please use /close to mark the forum thread as answered
one little side addition: exceptions should be exceptions, dont use them for normal control flow, they are pretty expensive under the hood performance wise
Eh, they're still pretty cheap. People get over-excited about micro-optimisations
hmmm what do you mean by not using them for normal control flow pls
like not to use them everywhere ?
Use them in "exceptional" cases, i.e. when a method couldn't do the thing which its name said it was supposed to do
Don't use them for normal, expected cases
a good example is $tryparse
When you don't know if a string is actually a number when handling user input, use
int.TryParse
(or variants, e.g. double.TryParse
)
TryParse
returns a bool
, where true
indicates successful parsing.
- Avoid int.Parse
if you do not know if the value parsed is definitely a number.
- Avoid Convert.ToInt32
entirely, this is an older method and Parse
should be preferred where you know the string can be parsed.
Read more here(But that's more to do with the fact that reasoning about control flow which uses non-local jumps is hard)
think about it like that. u want to try to open a door, instead of opening the door but if its locked u activate some alarm
yep I see, instead of using a try-catch block to give an exception when a file doesn't exist when we try to read it, we can simply use an if-statement instead, it's less overhead ?
Well, you can't just replace try-catch with an if-else
But you can check for the file's existence, and read it only if it exists
But, that's the prime example of where exceptions are the necessary approach. Check-then-read is a TOCTOU race
That's like the no. 1 example of when not to do check-then-read
Fair
Time-of-check to time-of-use
In software development, time-of-check to time-of-use (TOCTOU, TOCTTOU or TOC/TOU) is a class of software bugs caused by a race condition involving the checking of the state of a part of a system (such as a security credential) and the use of the results of that check.
TOCTOU race conditions are common in Unix between operations on the file sys...
ah I see, just read about the TOCTOU, didn't know about that
yeah, the when clause can create a "conditional catch block" ?
For division by zero for e.g, say we write a block of code where
result = num1/num2
. Here, we know that num2 can be 0 and if this is the case, we will get a DivisionByZero Exception, so in this case is it better to handle the exception using try catch block or to check if denominator is not 0 before proceeding with the division? I understood that any check made, like when checking if a file exists, an attacker can change contents of the file; is it possibile for the attacker to change what happens in our code also?In this case, it's better to check
*
0
is a valid value, not an exceptional state
* It won't cause any race conditions or anything
And, just to be clear about TOCTOU, for a code like
to break, the file would have to be deleted within nanoseconds of the checkyep I see
I think I now have a clearer understanding of exception handling, when it's more appropriate to use it and why, thanks !
$close
If you have no further questions, please use /close to mark the forum thread as answered
I noticed the catch block sometimes takes in argument and so requires the () but sometimes we omit it, how does it behave with and without the parentheses? Is there a reason to use it without the ()? Because, we can catch any exception using the Exception type, no ?
So we can have the following code:
We only use the "parameterized" catch block when we need the exception type object?
Basically
BTW, if code can throw multiple exceptions, you can have multiple
catch
blocksIn case we have multiple exceptions, the exception that may occur first should have its respective catch block in the first order, like order of catch block matters depending on the order in which the exception can occur ?
or well not really because of its type
The exception that occurs. What I mean, is some database query can throw, for example
ConflictException
or ConnectionWhateverException
or DatabaseNotFoundException
, and you can catch each of them individually
Only one catch
block will run, though
So if you catch Exception
first, it will catch all of them
Since all of those types would inherit Exception
ahhh I see
yep noted, thanks !
Exception-handling statements - throw and try, catch, finally - C# ...
Use the C# throw statement to signal an occurrence of an exception. Use the C# try statements to catch and process exceptions occurred in a block of code.
You can also use
when
to assert some things about exceptions
For example, most databases just throw a generic DatabaseException
that has the database's internal exception number stored inside
So you can do
etcyeah, just have a look at the docs, like we use a "subset" of a larger exception type; instead of using the exception name like IndexOutOfRange, their exist a code refering to that exception ?
No, you can't do something like
for
IndexOutOfRange
I just gave an example
Exceptions can have any properties you want — they're just classes after all — but are not guaranteed to have any
Meaning, it's not some inherent property of exceptions that they all have some numeric code to them
It's just the first thing that came to mind, because I had to deal with magic numbers like that when handling NpgSQL lolahhh I see
yep
Angius
REPL Result: Success
Console Output
Compile: 493.962ms | Execution: 40.208ms | React with ❌ to remove this embed.
yep make sense now, thanks !
:Ok:
Hello guys, I just started to read about the "throw" keyword which throws an exception by creating a new exception object of a specific type. I was wondering, why is it important to use the throw keyword or where do we use it? what are its use cases pls.
Like where would we not being able to use try catch block and need to stick with the throw keyword
u basically throw an exception when you dont know what to do with that unexpected error
eg,
File.ReadAllBytes(string path)
doesnt know how to handle the unexpected case that the file does not exist.
to signal that to the caller, it throws an exception.
so its the callers responsibility to handle that error.
that might be a closing the application/exiting the process or maybe showing an error dialog, or something completely different
throwing an exception is basically "hey something unexpected happened, here is the error, now clean up that mess yourself"
there is also one case i didnt mention yet, rethrow,
basically u have something like
basically u want the state of ur class/type to be valid all the time,
lets assume the DoSomethingThatMightThrow()
method modifies ur internal state.
due to the exception that state would become invalid the next time it is used, but catch the exception, fix the internal state to make it valid again, but still provide the caller with the exception of what went wrongYep I see, I have one question.
Consider this code:
Here, we want to find the Square Root of a number. What we did is we first check if number is negative. If so, then return a value of -1. Then the caller will check if result is successful or not then adjust its logic.
My question is, what is the correct way here, is it better to throw an exception or use simple code logic? Another example would be when checking for the age of a person, like if age is less than 0, raise/throw an exception so that caller can handle it or return some unsuccessful operation number. Does the throw keyword cause performance overhead like the try-catch blocks?
when to throw exceptions is quite use case dependent.
ur math example: this is a bit more complex because the existence of
NaN
, its a value to indicate that an operation wasnt possible, without throwing.
thats because often u have quite complex computations going on there and then check at certain points if its NaN
to see if there is a failure (u dont want a try catch block for every division, do ya?)
for the age of a person: as with each other, this type should maintain a stable state, because a negative age isnt possible, its the callers fault to provide the wrong values and it should throw an exception (an ArgumentOutOfRangeException
in this case)yep we don't want to use try catch block everytimes, same with if logic I guess
there are in the end 2 kinds of exceptions,
one that indicate bugs (like
ArgumentException
, NullReferenceException
) which u usually do not catch (or only catch them to log what went wrong)
the other kind is failure that is outside of ur control (eg the internet connection died because ur wifi sucks, or the human ripped out the usb stick while u write to that file)
(as a side note, there is actually a third kind of exception: the uncatchable, these u will not see unless u do something unsafe that is close to the system, its the kind of problems where the process itself can not recover from)yeah I see, I now have an overview of try-catch blocks and throw keywords and an idea of how to use them now but still need to practice by applying them, thanks !! will come back if I have further questions but should be okay for now