C# oracle : catch all exceptions relative to connectivity? - c#

In c#, can I catch all errors about (non) connectivity to an Oracle database?
I don't want to catch error about badly written query but only errors like No listener, connection lost...
If queries are badly written (or table are missing) then this is my fault.
But if Oracle or the network is down then this should be held by another department.

Write your code in which you build the connection in a try catch part:
try
{
BuildConnection(connectionString);
}
catch (OracleException ex)
{
//Connectivity Error
}

Errors between ORA-12150 to ORA-12236 are related to connection errors. A few examples:
ORA-12154: TNS:could not resolve the connect identifier specified
ORA-12152: TNS:unable to send break message
ORA-12157: TNS:internal network communication error
Please refer to https://docs.oracle.com/cd/E11882_01/server.112/e17766/net12150.htm

Simple answer for this Type of problem is Use Try Catch Block like
try
{
// your code
}
catch (OracleException ex)
{
}
MSDN HELP

Sure - you can catch specific exception types, or if they're all the same exception type, you can catch it, check to see if it's a specific type, and re-throw ones you don't want to handle. Not having your syntax, here's an example...
try
{
// your Oracle code
}
catch (OracleException ex)
{
if (ex.Message == "Something you don't want caught")
{
throw;
}
else
{
// handle
}
}

errors like No listener, connection lost are still caught in System.Data.SqlClient.SqlException, however, you may inspect ErrorCode and Errors to handle different situations accordingly, say, not listener or connection lost etc.
MSDN does not seem to document all possible errors, however, you may write a few unit tests or integration tests to learn what appear in ErrorCode and Errors, then write error handlers in production codes accordingly.
OracleException contains only ErrorCode not Errors. So you may be using switch(e.ErrorCode) to handle different situations.

I observed that each time a network exception occurs, then a SocketException can be found in inner exceptions.
I also observed that when a network exception occurs, the first inner exception is of type «OracleInternal.Network.NetworkException» but unfortunately, this class is internal...
Based on this observations, I would code something like this:
public void RunQuery()
{
try
{
var con = new OracleConnection("some connection string");
con.Open();
var cmd = con.CreateCommand();
// ...
cmd.ExecuteNonQuery();
}
catch (Exception ex) when (IsNetworkException(ex))
{
// Here, a network exception occurred
}
catch (Exception ex)
{
// Here, an other exception occurred
}
}
private static bool IsNetworkException(Exception ex)
{
var exTmp = ex;
while (exTmp != null)
{
if (exTmp is SocketException)
return true;
exTmp = exTmp.InnerException;
}
return false;
}

Related

How to differentiate between InvalidOperationException exception types?

How to detect the InvalidOperationException type
Here is the inner exception message:
System.InvalidOperationException: ExecuteNonQuery requires an open and available Connection. The connection's current state is closed.
I need to detect exactly this type of exceptions to handle it.
Can I know its HResult number or the exception code? or another way?
This code may help
try
{
//your code here...
}
catch (Exception exception) when (exception.InnerException is InvalidOperationException)
{
var exceptionMessage = "ExecuteNonQuery requires an open and available Connection";
if (exception.Message.Contains(exceptionMessage) || exception.InnerException.Message.Contains(exceptionMessage))
{
//handle it...
}
}
You can use a try/catch exception handling hierarchy, so that InvalidOperationException will be caught first and handled separately from other exception types such as the generic exception type.
try
{
// Normal workflow up here
}
catch (System.InvalidOperationException ioex)
{
// Handle InvalidOperationException
Console.WriteLine(ioex.StackTrace);
}
catch (System.Exception ex)
{
// Handle generic exception
Console.WriteLine(ex.StackTrace);
}
However, your question suggests that this will not work for you, because you mention an inner exception. In that case you probably need to do some type checking on the inner exception like this:
try
{
// Normal workflow up here
}
catch (System.Exception ex)
{
if (ex.InnerException is InvalidOperationException)
{
// Handle InvalidOperationException
}
else
{
// Handle generic exception
}
Console.WriteLine(ex.StackTrace);
}
Could you give us more context? It would make it easier for us to answer your question.
However, if I understand you correctly, you try to process 'something' with the inner exception. As of C# 6 there are exception filters available. For more information about exception filters see Exception filters.
The documentation also provides an example.
In your specific case, you could use the exception filter as follows:
try
{
// Do something that could cause a InvalidOperationException
}
catch (InvalidOperationException ex) when (ex.InnerException is SomeTypeOfException)
{
// Handle this type of exception
}
catch (InvalidOperationException ex) when (ex.InnerException is AnotherSomeTypeOfException)
{
// Handle this kind of exception
}

Is multiple try-catch in error sensitive code considered a good practice?

I have a code segment that is responsible for orchestrating the execution of a few modules and it is very sensitive to errors - I want to make sure I log and alert about every exception that occurs.
Right now I have something like this:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module A failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
try
{
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module B failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
// etc for other modules.
It looks to me that the multiple try-catch is making this segment less readable. Is it indeed the right thing to do?
Yes, it's the right thing.
But you should have the performance in in mind, maybe it's better to put all method calls in one try/catch and add stack trace and error information in the exception in the methiod itself.
public void ModuleA.DoSomethingA()
{
throw new Exception("Error in module A");
}
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
// get information about exception in the error message
}
You did well.
This way, you can process the error after each module. If you want to run it all and then do error handling, consider this alternative:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch(ModuleAException ex)
{
// handle specific error
}
catch(ModuleBException ex)
{
// handle other specific error
}
catch (Exception ex)
{
// handle all other errors, do logging, etc.
}
i think that depends on the approach that you want to follow.
It seems like you error messsages are different for each module that raises exception so i guess the approach that you followed is right.
you could have put the whole thing in a big try - catch block then in that case you will not know which module caused the exception as a generic excpetion gets printed.
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Either Module A or B failed", ex.Message);
// Log exception, send alerts, etc.
}
So if you want your exception handling to not be cleaner use the above code.
Otherwise what you followed is absolutely fine.

Is it ok to handle specific exception like this

I have seen such code in many places, is there any benefit of this..Or this is a wrong practice..
try
{
......
}
catch (NullReferenceException ex)
{
Data.LogError(ex, "Exception occourred while ...");
}
catch (IndexOutOfRangeException ex)
{
Data.LogError(ex, "Exception occourred while ...");
}
catch (Exception ex)
{
Data.LogError(ex, "Exception occourred while ...");
}
In context of specific exception handling.
There is benefit if you are going to handle the exceptions differently in the catch block (i.e. perform different actions as a result of the exception being thrown).
Otherwise you could remove the more specific exception handlers and just use the most generic:
catch(Exception ex)
Note: If the exception is being used purely for logging then sometimes it can be useful to re-throw the exception to bubble it up to the rest of the application:
try{
}
catch(Exception ex){
// Log exception here
throw;
}
This is even better than a generic catch, because you can choose what to do with a certain type of exception. Say, you want to show a message if a file doesn't exist, and offer to retry, but kill the application otherwise.
You can also handle exceptions differently, because they offer different properties (thanks to Rots for pointing that out):
try
{
}
catch(FileNotFoundException ex)
{
Console.WriteLine(ex.FileName + " not found");
//Retry
}
catch(Exception ex) // Exception does not contain ex.FileName
{
//Save stuff
//Exit
}
Only the first matching block will be executed.
The given approach is best in case if you wanted to handle/log any specific exception in it's own way. Also, ideal in scenario, where you can inform user with more apt details than giving generic messages. Now, if you don't want to handle different exceptions then you can goahead with one catch block, which catch all exception.

Try Catch handled at top of process

if I do this:
try
{
//code
}
catch (Exception)
{
throw;
}
Does the Exception go up with all its information?
The idea is to handle errors at the top of the app. There I'd execute some SQL sp to fill the admin's table so he's aware of exceptions.
I want to store Exception.Message and the source (method, function, whatever..) of the exception. But I don't know how to refer to "where" the exception happened. Is it Exception.Source? Exception.TargetSite?
Thanks.
The type of Exception will tell you what kind of exception it is (IndexOutOfRangeException, SqlException, etc) which you would react too accordingly:
try
{
//code
}
catch (SqlException ex)
{
// Handle code
}
catch (IndexOutOfRangeException ex)
{
// Handle code
}
catch (Exception ex)
{
// Handle code
}
As to where it is happening... you should be enclosing exception-prone areas with a try catch and not large code chunks. This way you will know where the exception derives from.
The Short answer is yes: just calling throw passes everthing regarding the exception up.
throw ex resets the stack trace (so your errors would appear to originate from HandleException)
throw doesn't - the original offender would be preserved.
(quoted from Mark Gravell)

Continue after try-catch-finally

This might sound like a weird question but I don't get it...
Let's say I have an application which connects to a server to do some stuff. This connect might fail and throw an exception which I can catch.
try {
Client.connect();
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
However, in case that the connect is succcesful the application shall continue...
try {
Client.connect();
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
// Talk to the server...
The "server talking" however is executed in any case. It doesn't matter if the exception occured or not.
How can I make sure that the "server talking" is only executed if the connect was successful? Do I have to move all of the following code inside the trystatement? What is a clean way to program such a behavior?
"Talk to the server" should happen in the try block, right after
Client.connect();
The easiest way is to just set a boolean. But there are many many many ways to deal with this.
bool connectionError = false;
try {
// connect
} catch (...) {
connectionError = true;
} finally {
// whatever
}
if (!connectionError) {
// talk to server.
}
Have another variable like clientConnected and set it to true right after Client.Connect(). Then outside the try-catch check for clientConnected before talking to the server.
Avoid doing everything in a single try-catch. You should use separate try-catch blocks for different actions that might throw exceptions, and catch specific exceptions as much as possible.
Typically you use try...catch statements for those statements which you expect to throw an Exception. Try...Catch defines its own scope, so you should declare any variables outside of the Try...Catch block (at least, those variables that you want to use outside of it).
If you want to know if an exception was thrown, then define the Exception variable above the Try...Catch. You can then examine it to determine if it is Null or not.
System.Exception ex;
try {
Client.connect();
} catch (ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
if (ex != null){ ... }
// Talk to the server...
You could log an event and then call some code to either try again or to cancel... or whatever you need to do.
Use some type of flag variable to indicate whether server is connected or not. If your method is returning a boolean variable then also it is ok.
int flag=0;
while(flag==0){
try {
Client.connect();
flag=1;
} catch (System.Exception ex) {
// Do some exception handling...
} finally {
// Do some cleanup...
}
}
//If server connects code

Categories

Resources