How to get ORA error code in C# exception? - c#

My code looks like this:
public bool myQuery(string cmd)
{
try
{
OracleCommand command = null;
command = new OracleCommand(cmd, sqlConnection);
command.ExecuteReader();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "error!");
return false;
}
return true;
}
My issue is when error ORA-02291 occurs in Oracle, its Exception is not caught. No error is shown, how do I catch this error ?

Check this:
if (ex.InnerException != null)
{
MessageBox.Show(ex.InnerException.Message, "error!");
}

catch (System.Data.OracleClient.OracleException ex)
{
int code = ex.Code;
// or
string eCode = ex.ErrroCode;
return false;
}
return true;

Related

Advice on how to refactor a nested try/catch block inside a using clause

A developer has written the following code below and I am trying to find a better way to refactor it:
try
{
using (var client = new WebClient())
{
var proxy = new WebProxy(address, portNo);
proxy.BypassProxyOnLocal = false;
proxy.UseDefaultCredentials = true;
client.UseDefaultCredentials = true;
result = client.DownloadString(httpURL);
}
}
catch (Exception ex)
{
log.Error("blah blah", ex);
try
{
SendNotification
}
catch (Exception emailEx)
{
log.Error("blahblah " + emailEx);
}
}
Is the using clause required to be inside a try/catch block, considering it itself is using try/finally? And then if an exception is thrown inside the using, how do I handle it?
Is there a better way to avoid the nested try/catch when sending a notification?
Try to call SendNotification when exception is thrown and handle exceptions in SendNotification():
try
{
using(var client = new WebClient())
{
var proxy = new WebProxy(address, portNo);
proxy.BypassProxyOnLocal = false;
proxy.UseDefaultCredentials = true;
client.UseDefaultCredentials = true;
result = client.DownloadString(httpURL);
}
}
catch (Exception ex)
{
log.Error("blah blah", ex);
SendNotification();
}
And SendNotification():
private void SendNotification()
{
try
{
// Here you are sending notifications
}
catch (Exception emailEx)
{
log.Error("blahblah " + emailEx);
}
}
The best way to avoid nesting is to make it in another function
catch (Exception ex)
{
log.Error("blah blah", ex);
FUNCTION_NAME()
}
private RETURN_TYPE FUNCTION_NAME()
{
try
{
SendNotification
}
catch (Exception emailEx)
{
log.Error("blahblah " + emailEx);
}
}
Many C# native libraries use the Try pattern to specify they will not throw:
For example:
bool Dictionary.TryAdd(element)
public DoEverything()
{
if(!TryDownload(..))
{
TrySendNotification();
}
}
public bool TryDownload(out result)
{
try {
using(var client = new WebClient())
{
var proxy = new WebProxy(address, portNo);
proxy.BypassProxyOnLocal = false;
proxy.UseDefaultCredentials = true;
client.UseDefaultCredentials = true;
result = client.DownloadString(httpURL);
return true;
}
}
catch (Exception ex)
{
log.Error("blah blah", ex);
return false;
}
}
public bool TrySendNotification()
{
try
{
// Here you are sending notifications
return true;
}
catch (Exception emailEx)
{
log.Error("blahblah " + emailEx);
return false;
}
}

DataReader.GetGuid is throwing The method or operation is not implemented error

This is my code
try
{
using (SafeDataReader reader = await this.SqlDataService.GetReaderAsync(command).ConfigureAwait(false))
{
while (reader != null && await reader.ReadAsync().ConfigureAwait(false))
{
response.Items.Value.Add(new SqlGetAllSitesResponse
{
SiteID = reader.GetGuid(reader.GetOrdinal("SiteID")),
URL = reader.GetString("URL"),
});
}
}
}
catch (Exception e)
{
response.Success = false;
response.ErrorMessage = e.Message;
}
it is throwing The method or operation is not implemented error. i do not understand the reason.please help.

Splitting data access and catching data to form

In my project I'm trying to write code that will be nice to understand.
I currently split my data access functions in a seperate class.
What I'm trying to achieve however, is to catch the errors back to my form. I am not getting this currently and I was wondering why.
In my form I have the following code:
private void btn_Save_ItemClick(object sender, ItemClickEventArgs e)
{
if (dal.updatePerson(ObjectAfterSaving))
{
MessageBox.Show("Updated!");
}
else
{
MessageBox.Show("error");
};
}
In my dal object (derived from the DataAccess_Person class), I have the following method:
public bool updatePerson(Person p)
{
conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Database"].ConnectionString);
SqlCommand command = new SqlCommand(#"UPDATE Person
SET PersonName = #PersonName
WHERE PersonID = #PersonID", conn);
command.Parameters.Add("#PersonName", SqlDbType.VarChar).Value = p.Name
{
try
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
int a = command.ExecuteNonQuery();
conn.Close();
if (a > 0)
{
return true;
}
else
{
return false;
}
}
catch (SqlException ex)
{
ex.ToString();
return false;
}
}
}
My question is: let's say if my method falls in the catch. Will my front end (form) show it (Sql Exception for example) ? Or will i just get 'error' ? And If I will just get error, how I can improve my code to show the Exception instead of error?
A simple way is to remove the try catch from your DAL and add it to the form. For example:
private void btn_Save_ItemClick(object sender, ItemClickEventArgs e)
{
var result = "Success";
try
{
dal.updatePerson(ObjectAfterSaving);
}
catch (SqlException sqlEx)
{
result = sqlEx.Message;
}
catch (Exception ex)
{
result = ex.Message;
}
MessageBox.Show(result);
}
Just note that there's a lot of ways you can do this. My preference is to not include DAL specific exception types in my UI. Instead I may return a custom result type that has an errorcode and message and let my UI display that or generate a custom message based on the error code.
You‘ll just get „error“ in case of a SqlException. All other exceptions will crash your program if you don‘t have a global exception handler. If you want to show the error message you could introduce an out variable for the error message:
bool successful = MyMethod(out string errorMessage)
if (!successful)
{
MessageBox.Show(errorMessage);
}
public bool MyMethod(out string errorMessage)
{
errorMessage = "";
try
{
// do some stuff
return true;
}
catch(Exception ex)
{
errorMessage = ex.Message;
return false;
}
}

How to handle ibm.data.db2.iseries exceptions

I have this code:
con = new iDB2Connection(connectString);
try { con.Open(); }
catch (iDB2ConnectionTimeoutException ex)
{ Console.WriteLine(ex.Message); }
catch (iDB2DCFunctionErrorException ex)
{ Console.WriteLine(ex.Message); }
catch (AccessViolationException ex)
{ Console.WriteLine(ex.Message); }
Close connection
if (con != null)
{
try
{
Console.WriteLine("CRASH IS AFTER THIS");
if (con.State != ConnectionState.Closed)
{
con.Close();
}
}
catch (iDB2ConnectionTimeoutException ex)
{
Console.WriteLine(ex.Message);
}
catch (iDB2DCFunctionErrorException ex)
{
Console.WriteLine(ex.Message);
}
catch (AccessViolationException ex)
{
Console.WriteLine(ex.Message);
}
catch (iDB2Exception ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
}
}
But I still get this nasty message when the Close connection is being run:
Unhandled Exception: IBM.Data.DB2.iSeries.iDB2DCFunctionErrorException: An unexp
ected exception occurred. Type: System.AccessViolationException, Message: Attem
pted to read or write protected memory. This is often an indication that other m
emory is corrupt.. ---> System.AccessViolationException: Attempted to read or wr
ite protected memory. This is often an indication that other memory is corrupt.
at IBM.Data.DB2.iSeries.CwbDc.DcDnIsAlive(Int32 functionNumber, IntPtr connec
tionHandle, IntPtr nullParm)
at IBM.Data.DB2.iSeries.MPConnection.IsAlive()
--- End of inner exception stack trace ---
at IBM.Data.DB2.iSeries.MPConnection.IsAlive()
at IBM.Data.DB2.iSeries.MPConnectionManager.GetConnection(iDB2Connection piDB
2Connection)
at IBM.Data.DB2.iSeries.iDB2Connection.Open()
I get this when I know the iSeries is down for maintenance.
How do I handle this so that the C# console application continues on?
Why don't you put it in the Finally block and use only one try/catch?
con = new iDB2Connection(connectString);
try
{
con.Open();
}
catch (iDB2ConnectionTimeoutException ex)
{
Console.WriteLine(ex.Message);
}
catch (iDB2DCFunctionErrorException ex)
{
Console.WriteLine(ex.Message);
}
catch (AccessViolationException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (con != null && con.State == ConnectionState.Open)
con.Close();
}

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");
}
}

Categories

Resources