I catch Exception.
I would like to do something if that is a specific error. I can easily identify it with the string.
However I wondered if there is a cleaner way to do this. For example, when I create my own wrapper for exception I add an index.
Is there such a thing in default exception?
The function I use that throws errors is an instantiation of RemoteWebDriver (selenium object). However I don't need an answer specific for that class.
To be more precise, I catch the following error: OpenQA.Selenium.WebDriverException.
However it may be thrown if there is a timeout when creating a driver or if a js file is closed. They have the save HResult.
So I see no way to differentiate them other than to check string unfortunately...
You can catch specific exceptions. For example...
try
{
//Do things with your RemoteWebDriver...
}
catch (ImportantException e)
{
//Do something important with this specific exception
}
catch (Exception e)
{
throw;
}
This code "does" something specific when and only when an Exception of type ImportantException gets thrown, but in all other cases, it does something else (in this example, it just throws the exception).
You can also use exception filters as of C#6. See: https://stackoverflow.com/a/4268291/1672990
Related
I want to be able to get access to e.ErrorDetails contents when an exception occurs in a try/catch block, but unfortunately I can't.
How could I do this without parsing the entire exception object?
try
{...}
catch (Exception e)
{Console.WriteLine(e.ErrorDetails);} //compile error!
Thank you
You need to have an expression of type IScriptEngineException. The simplest approach to that is probably to catch that specific exception. You can't use the interface for that directly, but you can use an exception filter to have the same effect as if you wrote catch (IScriptEngineException ex):
try
{
// ...
}
catch (Exception e) when (e is IScriptEngineException ex)
{
Console.WriteLine(ex.ErrorDetails);
}
// Potentially a more general catch block here
You should consider carefully whether you want to have a more general catch block (catching all exceptions) - without more context, we can't give much advice for that. "Catch all" blocks are generally appropriate only at the top level of a program - e.g. to avoid taking a server down when a single request fails, or to give diagnostic information in a console app before exiting.
So this code triggers CA1031.
try
{
// logic
}
catch (FileNotFoundException) // exception type
{
// handle error
}
While this one does not:
try
{
// logic
}
catch (FileNotFoundException ex) // exception var
{
// handle error
}
Because the exception type is meaningful, I don't need the ex in the first example. But it's not a a general exception type. It's not IOException or Exception. So why does it still trigger the CA1031?
So is there a difference between catch(FileNotFoundException) and catch(FileNotFoundException ex) outside the fact that I don't capture exception info?
So this code triggers CA1031
try
{
// logic
}
catch (FileNotFoundException) // exception type
{
// handle error
}
This occurs because a "general exception such as System.Exception or System.SystemException is caught in a catch statement, or a general catch clause such as catch() is used". To fix it, assign it and handle the error and or rethrow the general exception for it to be handled further up.
Upon further investigation, it seems this used to be an bug, you can see more here; it was a Roslyn issue for FxCop.
To Fix:
Just update the latest FxCop analyzers package and it should go way.
NuGet:
Install-Package Microsoft.CodeAnalysis.FxCopAnalyzers -Version 2.9.7
References:
CA1031
I have two Articles I use as basis for my Exception handling:
https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET
I also link those often when I notice Exception handling errors.
FileNotFound is clearly a exogenous Exception, so it is correct to catch it. However those articles also tell that as a general rule, to always log or expose those Exceptions. Ideally the result of Exception.ToString(). If you do not have a way to reference the caught exception, how could you do either of those two? You can only give a generic error message, but with none of the details you will actually need to debug it.
While there are many cases where you only want to expose the Exception type to the user, there is never one where you only want to log the Exception type. The linked articles mention that explicitly, but due to downvotes and comments it seems nessesary for me to repeat that.
So it is one of those cases where the argument is still going if it is a bug or a feature.
For me it certainly feels more like a feature. I would certainly call you out as potentiall issue, if I saw it in your code. It avoids you under-logging stuff. You could test if the error persist if you write throw; at the end of the catch block. This will re-throw on the exception, so a lack of being able to reference the exception in this ExceptionHandler would not be critical.
Apologies for the lack of information...
Is there a way to find out what is the specific Exception that is causing a call to throw the Exception?
Currently, I am catching all the Exceptions by doing catch(Exception e) but I know this is not good practices at all.
Is there a way to know from the Exception what is the specific one that caused the issue so I can be more granular?
You can get more information for the particular exception using different methods on it. Here I'm using the System.Diagnostics.Debug class to print in Visual Studio's output console. In your catch block:
using System.Diagnostics;
try
{
// do stuff
}
catch (Exception e)
{
Debug.WriteLine(e.GetType()); // Displays the type of exception
Debug.WriteLine(e.Message()); // Displays the exception message
}
You can see more here: Exception methods &
Exception properties
Option 1 - Documentation
Read the documentation of the method you are calling, if it is a Framework Class type (like SqlConnection.Open) the thrown exceptions are well documented.
Option 2 - Discover them at Run Time
If its a 3rd party library and documentation is limited then check the Exception at runtime using exception.GetType() and then add known exceptions you want to handle as catch blocks.
Personally I prefer to not add catch blocks at all where I am not sure if an Exception will materialize or not. If/When it does the debugger will break (if it is set to break) or you have a global catch all that logs and rethrows. Then you get the type and update your code accordingly. Where you add such a global Exception logger depends on the type of application you are developing. If you go the route of a global logger do take note that you 1) rethrow the Exception so the app breaks at runtime and not swallow it and 2) rethrow using throw; syntax (not throw ex;).
You can catch different types of exceptions. With this solution you are able to handle the different types easily.
try
{
//Try something
}
catch (StackOverflowException soe)
{
//Handle StackOverFlowException
}
catch (FormatException fe)
{
//Handle FormatException
}
//... Other exceptions
If you want to make it more specific for logging errors, try something like:
e.GetType()
Or, if you need some more information like the StackTrace or message:
e.ToString()
If you only want to catch a specific type of exception, you need to do something like:
try {
// someCode
} catch (SpecificExceptionType e) {
// someCode (e.g. Console.WriteLine(e.ToString()); )
}
catch (AnotherSpecificExceptionType e) {
// someCode (e.g. Console.WriteLine(e.ToString()); )
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Catching specific vs. generic exceptions in c#
Here's an example method
private static void outputDictionaryContentsByDescending(Dictionary<string, int> list)
{
try
{
//Outputs entire list in descending order
foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value))
{
Console.WriteLine("{0}, {1}", pair.Key, pair.Value);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I would like to know what exception clause to use apart from just Exception and if there is an advantage in using more specific catch clauses.
Edit: O.k thanks everyone
Catching individual types of Exceptions in your statement will allow you to handle each in a different way.
A blanket rule for Exception may be useful for logging and rethrowing Exceptions, but isn't the best for actually handling Exceptions that you may be able to recover from.
try
{
// open a file specified by the user
}
catch(FileNotFoundException ex)
{
// notify user and re-prompt for file
}
catch(UnauthorizedAccessException ex)
{
// inform user they don't have access, either re-prompt or close dialog
}
catch(Exception ex)
{
Logger.LogException(ex);
throw;
}
You should only really catch exceptions that you are expecting that code may throw. That way, if it throws something you didn't expect, it may either be something critical; something that should bubble up the call stack and possibly crash the application; or something you have not thought of.
For example, you may wish to handle IOExceptions thrown by I/O code so that you can relay the problem back to the user. However, the same operations may throw something more critical such as an AccessViolationException. In this case, you might want the program to terminate, or handle the problem in a different way.
Generic exception handling should only really be used in cases where you do not care what error occurred, and subsequently don't want it affecting the rest of your process.
The only potential cause for an exception that I see in your example is if list is null. OrderByDescending() should return an empty IEnumerable<> rather than a null reference.
If I read that correctly, it might make more sense to catch NullReferenceException:
try
{
...
} catch (NullReferenceException exception)
{
MessageBox.Show(...);
}
However, this really depends on the needs of your application. If your intention is just to alert the user or to log all exceptions, catching the Exception class is fine. If you need special handling for different types of exceptions - such as sending an email alert instead of just logging the message - then it makes sense to use specific exception types:
try
{
}
catch(NullReferenceException e)
{
//...
}
catch(StackOverflowException e)
{
//...
}
catch(Exception e)
{
/// generic exception handler
}
Which exception to use really depends on the code in the try block. In general you want to catch exceptions that you can do something with and let exceptions you have no power over move to high levels of your code where you can perform some action that makes since. One of the most common mistakes I see people make is attempting to catch errors that they have no ability to handle.
for example
Void ChoseFile()
{
try
{
string FileName = GetInputFile()
}
catch( InvalidFileSelectedException ex)
{
//In this case we have some application specific exception
//There may be a business logic failure we have some ability
//to infomr the user or do an action that makes sense
}
catch(FileNotFoundException exfilenot found)
{
//In this case we can do somthing different the the above
}
catch(Exception )
{
//Normal I would not use this case we have an error we don't know what to do
//with. We may not have a usefull action. At best we can log this exception
// and rethrow it to a higher level of the application that can inform the user
// fail the attempted action. Catching here would only suppress the failure.
}
}
You should always catch exceptions with an as specific class as possible.
If you know what to do if a file is locked, but you regard all other errors as unexpected and impossible to handle, you should catch System.IO.IOException and deal with the error. You should only catch Exception (or just catch {) for gracefully exiting.
Since you are dealing with a Dictionary.. then you want to look at these 2 exceptions
The key of keyValuePair is a null reference (Nothing in Visual Basic).
ArgumentException An element with the same key already exists in the Dictionary(TKey, TValue).
KekValuePair Exception
This is taken from the MSDN site
Use the exception type that you might expect but still not be able to prevent and that you can adequately handle. Let anything else bubble up to somewhere that might expect it or can handle it.
In your case here, I might expect that I would run into a NullReferenceException if the dictionary is null. But I would not catch it. This is something I can validate against instead
if (dictionary != null)
So there is no reason to allow an exception to even happen. Never use exceptions for control flow, and validate against known causes.
Some classes/methods will throw different exceptions, depending on the error. For example, you might be using the File class to write data to a file. You could write multiple Catch statements for the exception types you could recover from, and a generic Exception catch to log and bubble up anything that can't be recovered from.
By using Exception you catch all exceptions. Of you use IOException or StackOverflowException you'll only catch errors of that type.
a StackOverflowException catched by a Exception still hold the same message, stack trace etc.
Exception handling philosophy
I am sure you can find many other philosophies
Code defensively. Catching exceptions is more expensive than preventing the error in the first place.
Don't catch an exception and bury it by not handling it. You can spend many hours trying to find an error that has been suppressed.
Do log errors that you catch.
This helps in analyzing the problem. You can check to see if more than one user is having the same problem
I prefer a database for logging, but a flat file, or the event log are also suitable.
The database solution is easiest to analyze but may introduce additional errors.
If the error is due to bad data entered by the user, inform the user of the problem and allow them to retry.
Always allow an escape route if they cannot fix the problem.
Catch the error as close to the source as possible
This could be a database procedure, a method in a data access layer (DAL) or some other location.
Handling the exception is different than catching it. You may need to rethrow the exception so that it can be handled higher up the stack or in the UI.
Rethrowing the exception can be done in at least two ways.
throw by itself does not alter the stack.
throw ex does alter or add to the stack with no benefit.
Sometimes it is best not to catch an exception, but rather let it bubble up.
If you are writing services (web or windows) that do not have a user interface (UI) then you should always log the error.
Again, this is so that someone can analyze the log or database file to determine what is happening.
You always want someone to know that an error has occurred.
Having a lot of catch statements for a try block can make your code more difficult to maintain, especially if the logic in your catch blocks is complex.
Instead, code defensively.
Remember that you can have try catch blocks within catch blocks.
Also, don't forget to use the finally block where appropriate.
For example, closing database connections, or file handles, etc.
HTH
Harv
When the WCF service is turned off, I'm gonna catch this exception like this.
public List<ProjektyEntity> GetProjekty()
{
try
{
return this.channel.GetProjekty();
}
catch (EndpointNotFoundException exception)
{
//what to do at this point ?
}
}
But i don't know what to do in the catch block.I can return only an object of type List<ProjektyEntity> I'd like to write a message to the user,something like "The service is turned off" My presentation layer is ASP.NET MVC. Is there any strategy for this kind of situations?
There's a simple rule: If you don't know how to handle an exception, don't catch it.
Catching it and retuning null or an empty list would be about the worst thing you can do because it will be hard to debug where the error is coming from, or even that an error occured at all. If you do this you will have developers pulling their hair out.
Catching an exception and rethrowing it as throw e; is also bad because you lose the original stack. Rethrowing using throw; is OK sometimes if you have special clean up you need to do only if there is an error. Usually this is not the case. If you have cleanup that should be done whether or not there was an error, it belongs in the finally clause.
So in general unless there is something sensible you can do to recover from the error, just let the exception propogate to the caller. This is how exceptions are designed to work.
There are a few times when you might want to catch an exception to add more information (e.g. for logging), in which case you should ensure that you use an InnerException to avoid losing the original information:
try
{
foo(bar);
}
catch (Exception e)
{
throw new FooException("Foo failed for " + bar.ToString(), e);
}
but in general it's best not to do this unless you have a very good reason. Doing this prevents your users from catching a specific type of exception - they will catch your exception and then they need to switch on the type of the InnerException. Not fun. Just let the caller see the original exception.
I can see a few options here. Determining which is appropriate is probably dependent on the application.
Display an error and return null. Clean and simple, but inflexible. May not be what you want in every case where this function is used.
Don't catch it, let the caller catch this exception. It may be easier to determine the appropriate response from the calling function (ie. display a message / retry in a few seconds / etc)
Catch it and throw a new ServiceNotAvailableException Slightly more complex than option two, but will make your code clearer.
Just return null. Probably the least desirable approach unless this service being down is common and no big deal.
It seems to me that you should not catch this exception at that layer; you should let the exception propagate up to the controller layer and let the controller layer displays the message.
There are several approaches:
1) Don't catch the exception, and let the caller (user interface layer) handle it
2) Catch the exception so you can do anything you need to do, and then re-throw it
catch (EndpointNotFoundException exception)
{
CleanUpMyOwnState();
throw; // Pass the exception on the to the caller to handle
}
3) Convert the exception into another type (to make it easier to handle in the caller):
catch (EndpointNotFoundException exception)
{
CleanUpMyOwnState();
throw new InvalidOperationException("Endpoint was not found", exception);
}
4) catch it, and then return an error code (e.g null), so the caller doesn't need to use exception handling to deal with it (but there's no real advantage to doing this)
5) Catch the exception and report the error to the user yourself. This is probably a bad idea - you should keep all error reporting in your UI layer.
The exception is not supposed to be caught and handled in this context. It needs to be handled at much higher level having access to any console in general.
The best you can do here is just log the exception with necessary details and rethrow properly.
Create an exception object with enough debugging details and throw it to calling method
public List<ProjektyEntity> GetProjekty()
{
try
{
return this.channel.GetProjekty();
}
catch (EndpointNotFoundException exception)
{
'Write here Some Clean Up Codes
' Log it somewhere on your server so that you can fix the error
}
}