My code is currently
using(var driver = new driver()){something}
And I want to be able to catch exceptions. However I only want to catch exceptions thrown by "driver = new driver". Looking online I can find how to catch exceptions thrown by the whole thing or by "something" but I cannot work out how to put a try-catch into the "using" parameter.
It's a very strange requirement, but whatever that's your call.
You should get rid of the using completely, and handle the dispose yourself (which has the same result).
This is what you want:
driver driver = null;
try
{
try
{
driver = new driver();
}
catch(Exception ex)
{
// Here is your specific exception.
}
// Do something
}
finally
{
if(driver != null)
driver.Dispose();
}
Just do it:
Driver driver = null;
try
{
driver = new Driver();
}
catch()
{
// do whatever, throw, fail, return...
}
// if you did not break out of your logic in the catch (why not?)
// add an if(driver != null) before you proceed
using(driver)
{
// something
}
You can add a method to construct your driver and put your try/catch in there:
private static Driver CreateDriver()
{
try
{
return new Driver();
}
catch(Exception ex)
{
// whatever other exception handling you want
return null;
}
}
using(var driver = CreateDriver())
{
// something
}
Of course, if you do this, when your something code is executing inside the using block, driver may be null, so you'll need to check for this, e.g.:
using(var driver = CreateDriver())
{
if (driver != null)
{
// something
}
}
The "using" clause, primarily function is to dispose managed code resources once the process inside the clause has been completed. It "hides" a try catch block inside it, but if you really want to handle errors, you need to do it yourself.
eg.
Try
{
//do stuff
}
catch (exception ex)
{
//handle exception
//resource.Dispose();
}
After you handle your exceptions, you should dispose the unused resources by calling .Dispose(), assuming that the latter is a managed code resource and encapsulates the IDisposable interface
Related
I have a try-catch-finally block like below and I need to log the process's result in the finally block. So I need to know the result in finally block to be able to do it.
var isSucceed = false;
try
{
Do();
isSucceed = true;
}
catch(Exception ex)
{
isSucceed = false;
}
finally
{
_logger.LogInformation($"The process has been completed. Is Succeed = {isSucceed}");
}
So is there any property or method which provides if try block was called?
try
{
Do();
}
catch(Exception ex)
{
}
finally
{
var isSucceed = <isTryCalled>;
_logger.LogInformation($"The process has been completed. Is Succeed = {isSucceed}");
}
No - but you can safe the exception beforehand:
Exception error;
try
{
Do();
}
catch (ArgumentNullException ex)
{
// Safe the ex
error = ex;
}
catch (Exception ex)
{
// Safe the ex
error = ex;
}
finally
{
var isSucceed = error == null;
if (isSucceed)
_logger.LogInformation($"The process has been completed successfully");
else
_logger.LogError("The process faulted.", error);
}
The first piece of code you have seems to do what you want very well, but could probably do with some minimisation(a):
var succeeded = true;
try {
Do();
} catch(Exception ex) {
succeeded = false;
} finally {
// succeeded is false if exception happened.
}
But, to be honest, if you want to do something on exception, why not just do it in the exception block?
In any case, C# does not provide this information, you will have to maintain it yourself, as per the example.
(a) It may be preferable, in the case where you may add future exceptions, to assume failure and flag success at the end of the try block. That way, you don't have to remember to flag failure in every single except block. That option would be a minor change:
var succeeded = false;
try {
Do();
succeeded = true;
} catch(Exception1 ex) {
// No need to change succeeded here.
} catch(Exception2 ex) {
// Or here.
} catch(Exception3 ex) {
// Or, yes, you guessed it, here either :-)
} finally {
// succeeded is false if exception happened.
}
Of course, once you get to that point, you may also want to know which except block was triggered, so a simple boolean flag will not suffice. An enumeration is one possibility, another is storing the exception itself. Both of these would be initialised to "no exception" before the try block and then set to a specific value in each except block.
In that case, this footnoted solution (assuming a failure then having the try block flag success at the end) wouldn't work since you can't really assume a specific failure.
How to check if a function throws an exception in c#?
public List<string> GetFileNames()
{
try
{
// do something
// return something
}
catch(Exception ex)
{
// do something
// log something
}
}
then i will call GetFileNames() somewhere in my code, but I want to check if it throws an exception,
like,
var list = GetFileNames(); // can be 0 count
if(GetFileNames() throws an error)
{
DoThisMethod()
}
else
{
DoThisOtherMethod();
}
You have a lot of options here:
This is generally done with a Try... pattern like TryParse.
bool TryGetFileNames(out List<string> fileNames)
You can also return null.
You can"t do this in c#.
The closest thing to what you are describing is the "checked exceptions" which are implemented in java. In such case the function will declare it is throwing some exception like so :
public void foo() throws IOException {
// your code
}
At compile time you will be forsed to take care of this by either enclosing this in TryCatch block or propagate this the same way in your function.
In c# enclose the function in TryCatch block and use different function in case of faliure.
The fundamental problem is that you're attempting to handle an exception when you're not able to do so.
If GetFilenames cannot recover from the exception, it should throw an exception itself. That may be by omitting a try/catch entirely, or by catching it, wrapping and re-throwing.
public List<string> GetFilenames() {
try {
...
} catch (Exception e) {
throw new FileLoadException("Failed to get filenames", e);
// Or if you don't want to create custom exceptions, perhaps use an InvalidOperationException
}
}
Failing that, if you don't actually need to abstract the functionality, don't catch the exception in GetFilenames at all, then call it like this:
try {
var list = GetFilenames()
DoSomething();
} catch (Exception e) {
DoSomethingElse();
}
I think you can make it simpler:
public void ICallGetFileNames()
{
var list = new List<YourObject>();
try
{
list = GetFileNames();
DoThisOtherMethod();
}
catch (Exception ex)
{
DoThisMethod();
}
}
This way, if the exception is thrown by your GetFileNames method, the DoThisOtherMethod() won't be called, since your code is going directly to the Exception block. Otherwise, if no exception is thrown, your code will call the DoThisOtherMethod just after the GetFileNames method.
I am wondering can try..catch force execution to go into the catch and run code in there?
here example code:
try {
if (AnyConditionTrue) {
// run some code
}
else {
// go catch
}
} catch (Exception) {
// run some code here...
}
try{
if (AnyConditionTrue){
//run some code
}
else{
throw new Exception();
}
}
catch(){
//run some code here...
}
But like Yuck has stated, I wouldn't recommend this. You should take a step back at your design and what you're looking to accomplish. There's a better way to do it (i.e. with normal conditional flow, instead of exception handling).
Rather than throwing an Exception in the else, I would recommend extracting the code from your catch into a method and call that from your else
try
{
if (AnyConditionTrue)
{
MethodWhenTrue();
}
else
{
HandleError();
}
}
catch(Exception ex)
{
HandleError();
}
Yes, you have to throw exception :
try
{
throw new Exception("hello");
}
catch (Exception)
{
//run some code here...
}
An effective way to throw an Exception and also jump to Catch as so:
try
{
throw new Exception("Exception Message");
}
catch (Exception e)
{
// after the throw, you will land here
}
if(conditiontrue)
{
}
else{
throw new Exception();
}
Yes, if you throw the exception that you intend to catch from within the try, it will be caught in the catch section.
I have to ask you why you would want to do this though? Exception handling is not meant to be a substitute for control flow.
I think what you want is a finally block: http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx
see this
try
{
doSomething();
}
catch
{
catchSomething();
throw an error
}
finally
{
alwaysDoThis();
}
This is different if/when you do this:
try
{
doSomething();
}
catch
{
catchSomething();
throw an error
}
alwaysDoThis();// will not run on error (in the catch) condition
the the this last instance, if an error occurs, the catch will execute but NOT the alwaysDoThis();. Of course you can still have multiple catch as always.
As cadrel said, but pass through an Exception to provide more feedback, which will be shown in the innerException:
try
{
if (AnyConditionTrue)
{
MethodWhenTrue();
}
else
{
HandleError(new Exception("AnyCondition is not true"));
}
}
catch (Exception ex)
{
HandleError(ex);
}
...
private void HandleError(Exception ex) {
throw new ApplicationException("Failure!", ex);
}
public class CustomException: Exception
{
public CustomException(string message)
: base(message) { }
}
//
if(something == anything)
{
throw new CustomException(" custom text message");
}
you can try this
You could throw an exception to force a catch
throw new Exception(...);
why are you catching an exception? Why not just run the code in your "else" block? If you MUST do it that way, just throw a new exception
throw new Exception();
Slight resurrection, but I wanted to add both a sample (primarily like others) and a use case.
public int GetValueNum(string name)
{
int _ret = 0;
try
{
Control c = (extendedControls.Single(s => s.ValueName == name) as Control);
if (c.GetType() == typeof(ExtendedNumericUpDown))
_ret = (int)((ExtendedNumericUpDown)c).Value;
else
throw new Exception();
}
catch
{
throw new InvalidCastException(String.Format("Invalid cast fetching .Value value for {0}.\nExtendedControllerListener.GetValueNum()", name));
}
return _ret;
}
In my case, I have custom controls - a handful of controls that use a base Windows.Forms control, but add two bools and a string for tracking, and also automatically get registered to a Singleton List<T> so they can be properly fetched without drilling down through control containers (it's a tabbed form).
In this case, I'm creating some methods to easily get values (.Value, .Text, .Checked, .Enabled) by a name string. In the case of .Value, not all Control objects have it. If the extended control is not of type ExtendedNumericUpDown, it IS an InvalidCastException as the method should not be called against that type of control. This isn't flow, but the prescribed usage of invalid cast. Since Control doesn't naturally have a .Value property, Visual Studio won't let me just force an attempt and fail after.
How to correctly let an exception to bubble up?
If I use Try-Catch when calling a method, is just throwing an exception inside a method like not trying to catch it at all?
For illustration: Are these approaches do the same work?
Example 1:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
...
}
Example 2:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
try
{
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
}
catch (Exception)
{
throw;
}
...
}
Yes, those 2 approaches have almost the same effect; rethrowing will unwind the stack of the exception - meaning the stack frames "below" the method where the throw; will be discarded. They'll still be in the stack trace, but you won't be able to access their local variables in the debugger unless you break on thrown exceptions.
A catch/throw block like the one below where you don't do anything with the exception (like logging), is useless:
catch (Exception)
{
throw;
}
Remove it to clean up, in both your samples. In general, avoid entering a catch block if possible
And your method has another exception related problem, it does not free resources properly. The tr2.Close(); belongs in a finally clause but it's much easier to let the compiler handle that with a using() {} block :
void MyFileHandlingMethod()
{
...
using (TextReader tr2 = new StreamReader(nfilepath))
{
resultN = tr2.ReadLine();
} //tr2.Dispose() inserted automatically here
...
}
First of all you should use the using block with resources as this will take care of closing your resources correctly. The second example is pretty much useless as you don't do any work in the exception handler. Either you should remove it, or wrap it in another Exception to add some information.
Yes, the result is the same.
However, both will result in an unclosed stream if there is an error while reading it. You should use a using block or a try ... finally to make sure that the stream is closed:
using (TextReader tr2 = new StreamReader(nfilepath)) {
resultN = tr2.ReadLine();
}
Note that there is no Close in this code. The using block will dispose the StreamReader, which will close the stream.
The using block is compiled into a try ... finally which it uses to make sure that the StreamReader is always disposed, but the exception will bubble up to the calling method.
I suggest you use your first example, with these changes:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...";
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
throw; // rethrow the same exception.
}
// no need for second catch}
You probably want to rethrow the exception once you have logged it, because you are not doing any actual recovery from the error.
I know how to use try-catch-finally. However I do not get the advance of using finally as I always can place the code after the try-catch block.
Is there any clear example?
It's almost always used for cleanup, usually implicitly via a using statement:
FileStream stream = new FileStream(...);
try
{
// Read some stuff
}
finally
{
stream.Dispose();
}
Now this is not equivalent to
FileStream stream = new FileStream(...);
// Read some stuff
stream.Dispose();
because the "read some stuff" code could throw an exception or possibly return - and however it completes, we want to dispose of the stream.
So finally blocks are usually for resource cleanup of some kind. However, in C# they're usually implicit via a using statement:
using (FileStream stream = new FileStream(...))
{
// Read some stuff
} // Dispose called automatically
finally blocks are much more common in Java than in C#, precisely because of the using statement. I very rarely write my own finally blocks in C#.
You need a finally because you should not always have a catch:
void M()
{
var fs = new FileStream(...);
try
{
fs.Write(...);
}
finally
{
fs.Close();
}
}
The above method does not catch errors from using fs, leaving them to the caller. But it should always close the stream.
Note that this kind of code would normally use a using() {} block but that is just shorthand for a try/finally. To be complete:
using(var fs = new FileStream(...))
{
fs.Write(...);
} // invisible finally here
try
{
DoSomethingImportant();
}
finally
{
ItIsRidiculouslyImportantThatThisRuns();
}
When you have a finally block, the code therein is guaranteed to run upon exit of the try. If you place code outside of the try/catch, that is not the case. A more common example is the one utilized with disposable resources when you use the using statement.
using (StreamReader reader = new StreamReader(filename))
{
}
expands to
StreamReader reader = null;
try
{
reader = new StreamReader(filename);
// do work
}
finally
{
if (reader != null)
((IDisposable)reader).Dispose();
}
This ensures that all unmanaged resources get disposed and released, even in the case of an exception during the try.
*Note that there are situations when control does not exit the try, and the finally would not actually run. As an easy example, PowerFailureException.
Update: This is actually not a great answer. On the other hand, maybe it is a good answer because it illustrates a perfect example of finally succeeding where a developer (i.e., me) might fail to ensure cleanup properly. In the below code, consider the scenario where an exception other than SpecificException is thrown. Then the first example will still perform cleanup, while the second will not, even though the developer may think "I caught the exception and handled it, so surely the subsequent code will run."
Everybody's giving reasons to use try/finally without a catch. It can still make sense to do so with a catch, even if you're throwing an exception. Consider the case* where you want to return a value.
try
{
DoSomethingTricky();
return true;
}
catch (SpecificException ex)
{
LogException(ex);
return false;
}
finally
{
DoImportantCleanup();
}
The alternative to the above without a finally is (in my opinion) somewhat less readable:
bool success;
try
{
DoSomethingTricky();
success = true;
}
catch (SpecificException ex)
{
LogException(ex);
success = false;
}
DoImportantCleanup();
return success;
*I do think a better example of try/catch/finally is when the exception is re-thrown (using throw, not throw ex—but that's another topic) in the catch block, and so the finally is necessary as without it code after the try/catch would not run. This is typically accomplished with a using statement on an IDisposable resource, but that's not always the case. Sometimes the cleanup is not specifically a Dispose call (or is more than just a Dispose call).
The code put in the finally block is executed even when:
there are return statements in the try or catch block
OR
the catch block rethrows the exception
Example:
public int Foo()
{
try
{
MethodThatCausesException();
}
catch
{
return 0;
}
// this will NOT be executed
ReleaseResources();
}
public int Bar()
{
try
{
MethodThatCausesException();
}
catch
{
return 0;
}
finally
{
// this will be executed
ReleaseResources();
}
}
you don't necessarily use it with exceptions. You may have try/finally to execute some clean up before every return in the block.
The finally block always is executed irrespective of error obtained or not. It is generally used for cleaning up purposes.
For your question, the general use of Catch is to throw the error back to caller, in such cases the code is finally still executes.
The finally block will always be executed even if the exception is re-thrown in the catch block.
If an exception occurs (or is rethrown) in the catch-block, the code after the catch won't be executed - in contrast, code inside a finally will still be executed.
In addition, code inside a finally is even executed when the method is exited using return.
Finally is especially handy when dealing with external resources like files which need to be closed:
Stream file;
try
{
file = File.Open(/**/);
//...
if (someCondition)
return;
//...
}
catch (Exception ex)
{
//Notify the user
}
finally
{
if (file != null)
file.Close();
}
Note however, that in this example you could also use using:
using (Stream file = File.Open(/**/))
{
//Code
}
For example, during the process you may disable WinForm...
try
{
this.Enabled = false;
// some process
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.Enabled = true;
}
I am not sure how it is done in c#, but in Delphi, you will find "finally" very often. The keyword is manual memory management.
MyObject := TMyObject.Create(); //Constructor
try
//do something
finally
MyObject.Free();
end;