Catch oledb Exception with a specific error code - c#

I'm trying to catch a duplicate key violation. I can see the System.OleDB.OleDBException in the Intellisense pop up, but the inner exception is null. How do I access the Error Code in the System.OleDB.OleDBException?
Greg
try
{
MyData.ConExec(sSQL);
}
catch (Exception ex)
{
OleDbException innerException = ex.InnerException as OleDbException;
if (innerException.ErrorCode == -2147217873)
{
// handle exception here..
}
else
{
throw;
}
}

don't declare an instance of the exception. It will surely return empty if you do.
try
{
MyData.ConExec(sSQL);
}
catch (OleDbException ex)
{
// handle excpetion here...
if (ex.ErrorCode == -2147217873)
{
}
}
catch (Exception e)
{
// if other exception will occur
}

Related

ASP.NET Core Web API try catch exception question

In my API, I have over 25 API controllers, in every controller, using the following code to catch exception, I think it is too many code here, any good suggestion for the structure, thanks.
try
{
*code here*
}
catch (UnauthorizedAccessException ex)
{
}
catch (BadRequestException ex)
{
}
catch (HttpRequestException ex)
{
}
catch (TimeoutRejectedException ex)
{
}
catch (FileNotFoundException ex)
{
}
catch (SqlException ex)
{
}
catch (ValidationException ex)
{
}
catch (Exception ex)
{
}
Any simple way to do that.
IF
you plan to handle each exception separately - your approach is the way to go. I suggest to use this "ugly" code simply because it is more readable. If all your exceptions have common handling (for example logging) - you can use only catch (Exception e) and call your logging methods. This will work for all types of exceptions.
OR
If you decide that some of your exceptions might have common handling - you can go with:
try
{
// do
}
catch (Exception e)
{
if (e is BadRequestException ||
e is HttpRequestException ||
e is TimeoutRejectedException )
{
// Log exception
}
}
OR
A good approach is to use a delegate for exception handling. Since you're going to log exceptions, the delegate will handle this.
Action<Exception> HandleError = (e) => {
// Log exception
};
catch (UnauthorizedAccessException e) { HandleError(e); }
catch (BadRequestException e) { HandleError(e); }
catch (HttpRequestException e) { HandleError(e); }
OR
You can combine the first and the second approach
if (e is BadRequestException ||
e is HttpRequestException ||
e is TimeoutRejectedException )
{
HandleError(e);
}

How to go from one exception handler to another?

The best way to explain my question is with the following pseudo-code:
try
{
//Do work
}
catch (SqlException ex)
{
if (ex.Number == -2)
{
debugLogSQLTimeout(ex);
}
else
{
//How to go to 'Exception' handler?
}
}
catch (Exception ex)
{
debugLogGeneralException(ex);
}
Exception ex = null;
try
{
//Do work
}
catch (SqlException sqlEx)
{
ex = sqlEx;
if (ex.Number == -2)
{
//..
}
else
{
//..
}
}
catch (Exception generalEx)
{
ex = generalEx;
}
finally()
{
if (ex != null) debugLogGeneralException(ex);
}
The first catch clause that matches is the only one that can possibly run on the same try block.
The best way I can think of to do what you're attempting is to include casts and conditionals in the more general type:
try
{
//Do work
}
catch (Exception ex)
{
var sqlEx = ex as SqlException;
if (sqlEx != null && sqlEx.Number == -2)
{
debugLogSQLTimeout(ex);
}
else
{
debugLogGeneralException(ex);
}
}
If you find yourself writing this over and over again throughout your data layer, at least take the time to encapsulate it in a method.
I do not believe there is any way to do this as the catch blocks are in different scopes. There's no way to re-throw without exiting the try block and no way to 'call' the final catch block because it's only triggered during an exception.
I would suggest the same as roman m above and just make the same call. Otherwise you have to do something really bad. Like the below crazy code which you should never ever use but i included because it does something like what you want.
In general I think what you are doing is controlling normal flow via exceptions which isn't recommended. If you are trying to track for timeouts, you should probably just handle that another way.
Note that you could do something like the code below with the insanity of a goto statement, but i included it so no one can forget what a bad idea this is. =)
void Main()
{
Madness(new NotImplementedException("1")); //our 'special' case we handle
Madness(new NotImplementedException("2")); //our 'special' case we don't handle
Madness(new Exception("2")); //some other error
}
void Madness(Exception e){
Exception myGlobalError;
try
{
throw e;
}
catch (NotImplementedException ex)
{
if (ex.Message.Equals("1"))
{
Console.WriteLine("handle special error");
}
else
{
myGlobalError = ex;
Console.WriteLine("going to our crazy handler");
goto badidea;
}
}
catch (Exception ex)
{
myGlobalError = ex;
Console.WriteLine("going to our crazy handler");
goto badidea;
}
return;
badidea:
try{
throw myGlobalError;
}
catch (Exception ex)
{
Console.WriteLine("this is crazy!");
}
}
// Define other methods and classes here

Throw and catch exception in same method

In my method that writes to a database, I handle errors as shown in the code below. In catch (DbUpdateException ex) I want to re-throw the exception and catch it in the last catch (Exception ex).
Is that possible and how to do that? Code below doesn't do that.
using (Entities context = new Entities())
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw
new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
catch (Exception ex)
{
throw
new Exception("Error");
}
}
The following would be better:
context.Office.Add(office);
retVal = context.SaveChanges();
Let the except bubble up. No need to catch stuff if all you are going to do is re-throw.
Note: throw ex; will reset the stack trace - you want to do throw; normally.
If you want to catch exceptions from other catches then they cannot be on the same level.
Your current code has this structure:
try
{
}
catch (...)
{
}
catch (...)
{
}
You need to change it to:
try
{
try
{
}
catch (...)
{
// throw X
}
}
catch (...)
{
// catch X here
}
But you should think very carefully if you really want/need this. It does not look like a productive error handling pattern.
And see this answer for the 4 different ways to (re)throw an exception and their consequences.
have you tried try nesting your try...catch blocks?
using (Entities context = new Entities())
{
try
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
catch (Exception ex)
{
throw new Exception("Error");
}
}
A try-catch processes only one catch block and they are evaluated in order. Therefore, if you really need this functionality you'll need to put a try-catch inside of a try-catch, like this:
using (Entities context = new Entities())
{
try
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw
new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
catch (Exception ex)
{
throw
new Exception("Error");
}
}
Try this:
void YourMethod()
{
using (Entities context = new Entities())
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
throw
new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
}
Then when you call your method enclose it with try catch block
try
{
YourMethod()
}
catch (Exception ex)
{
throw
new Exception("Error");
}
When you plan to nest your try-catch-block as described by "paul" be aware of the exception type:
using (Entities context = new Entities())
{
try
{
try
{
context.Office.Add(office);
retVal = context.SaveChanges();
}
catch (DbUpdateException ex)
{
SqlException innerException = ex.GetBaseException() as SqlException;
if (innerException != null && innerException.Number == (int)SQLErrorCode.DUPLICATE_UNIQUE_CONSTRAINT)
{
// this exception will be catched too in outer try-catch block <--------
throw new Exception("Error ocurred");
}
//This is momenty where exception is thrown.
else
{
throw ex;
}
}
}
// Catch (DbUpdateException ex) if you plan to have the rethrown exception to be catched <------------
catch (Exception ex)
{
throw new Exception("Error");
}
}

Can I not catch a specific or custom exception?

I dont want to catch some exception. Can I do it somehow?
Can I say something like this:
catch (Exception e BUT not CustomExceptionA)
{
}
?
try
{
// Explosive code
}
catch (CustomExceptionA){ throw; }
catch (Exception ex)
{
//classic error handling
}
try
{
}
catch (Exception ex)
{
if (ex is CustomExceptionA)
{
throw;
}
else
{
// handle
}
}
Starting with C# 6, you can use an exception filter:
try
{
// Do work
}
catch (Exception e) when (!(e is CustomExceptionA))
{
// Catch anything but CustomExceptionA
}
You can filter it:
if (e is CustomExceptionA) throw;
And of course you can catch it and rethrow it:
try
{
}
catch (CustomExceptionA) { throw; }
catch (Exception ex) { ... }
First off, it's bad practice to catch Exception unless you log and re-throw it. But if you must, you need to catch your custom exception and re-throw it like so:
try
{
}
catch (CustomExceptionA custome)
{
throw custome;
}
catch (Exception e)
{
// Do something that hopefully re-throw's e
}
After being schooled by #Servy in the comments, I thought of a solution that'll let you do [what I think] you want to do. Let's create a method IgnoreExceptionsFor() that looks like this:
public void PreventExceptionsFor(Action actionToRun())
{
try
{
actionToRun();
}
catch
{}
}
This can then be called like this:
try
{
//lots of other stuff
PreventExceptionsFor(() => MethodThatCausesTheExceptionYouWantToIgnore());
//other stuff
}
catch(Exception e)
{
//do whatever
}
That way, every line except for the one with PreventExceptionsFor() will throw exceptions normally, while the one inside PreventExceptionsFor() will get quietly passed over.

C# value is declared but never used

I have a try and catch where I am catching different error types:
catch (XmlException XmlExp)
{
return false;
}
catch (XmlSchemaException XmlSchExp)
{
return false;
}
catch (Exception GenExp)
{
throw GenExp;
}
Notice that XMLException XMLExp is declared but never used. Is it possible to catch the XMLException without declaring a local variable?
Is this valid code:
catch (XmlException)
{
return false;
}
Yes, like this
catch (XmlException)
{
return false;
}
catch (XmlSchemaException)
{
return false;
}
catch (Exception GenExp)
{
// inspect or use GenExp
throw;
}
Do this
catch (XmlException)
{
return false;
}
catch (XmlSchemaException)
{
return false;
}
catch (Exception)
{
throw;
}
Just use
catch (XmlException)
{
throw;
}
When you throw a specific exception object like throw ex the stack trace gets overridden.
Yes. Just miss out the variable name:
catch (XmlException)
{
return false;
}
Yes you can:
catch (XmlException)
{
return false;
}
Of course, all other rules regarding exceptions apply - i.e. not using them for flow control, avoiding any situations where they might be thrown, etc.
catch (XmlException)
{
return false;
}
catch (XmlSchemaException)
{
return false;
}
catch (Exception GenExp)
{
throw GenExp;
}
Just omit the variable name.
For the last catch I'd advise using throw; instead of throw GenExp - as the latter loses the call stack. Although if you're really doing nothing more than a rethrow then just omit the whole catch block.
catch (Exception unknownException)
{
throw new Exception("Unknown error.", unknownException);
}
catch
{}
Is also valid code and catches all exceptions.
Important Notice!
It is a extremely BAD programming style - to use of similar constructions:
try
{
// smth
}
catch(IOException e)
{
throw e;
}
It means, that the exception stack will begin with this point (of stack), and you can lose any stack frames, which are lower than this point.
Correct:
try
{
//smth
}
catch(IOException e)
{
throw;
}
1- i think you was supposed to do this by yourself.
2- catch (XmlException) //valid
{
return false;
}
catch (XmlSchemaException) //valid
{
return false;
}
catch (Exception GenExp)
{
throw GenExp;
}
//valid but doesn't make sense because the Exception will happen and there is no try catch block to handel it

Categories

Resources