private void SetConnection(string id, string classCode)
{
try
{
_connection = new SqlConnection { ConnectionString = Settings.Default.CurrentConnection };
_connection.Open();
while (_connection.State == ConnectionState.Connecting || _connection.State == ConnectionState.Closed)
Thread.Sleep(1000);
_command = new SqlCommand(Settings.Default.EligibilityBenefitSP, _connection);
if (_command != null) _command.CommandType = CommandType.StoredProcedure;
_command.Parameters.Add("#ClassCode", SqlDbType.NVarChar).Value = classCode;
_command.Parameters.Add("#Id", SqlDbType.NVarChar).Value = id;
}
catch (Exception e)
{
throw new Exception(e.Message + " " + Settings.Default.EligibilityBenefitSP);
}
}
public Collection<EligibilityClassBenefit> ExtractEligibilityClassBenefit(string id, string classCode)
{
SetConnection(id, classCode);
Collection<EligibilityClassBenefit> eclassBene = new Collection<EligibilityClassBenefit>();
SqlDataReader reader = null;
try
{
_command.CommandTimeout = 420;
if (_connection.State == ConnectionState.Open)
reader = _command.ExecuteReader(CommandBehavior.CloseConnection);
else
throw new Exception("Connection Closed");
/* no data */
if (!reader.HasRows) return null;
while (reader.Read())
{
EligibilityClassBenefit eligibilityClassBenefit = new EligibilityClassBenefit
{
EffectiveDate = reader["EffectiveDate"].ToString(),
EndDate = reader["EndDate"].ToString(),
InitialEffectiveDate = reader["InitialEffectiveDate"].ToString(),
IsAdministrativeServicesOnly = reader["IsAdministrativeServicesOnly"].ToString(),
EffectiveProvision = reader["EffectiveProvision"].ToString(),
ProbationPeriod = reader["ProbationPeriod"].ToString(),
UnderwritingType = ExtractUnderwritingType(id),
ProbationPeriodUnit = reader["ProbationPeriodUnit"].ToString(),
StateOfIssue = reader["StateOfIssue"].ToString(),
};
BenefitData benefitData = new BenefitData();
eligibilityClassBenefit.Benefit = benefitData.ExtractBenefit(reader, id, classCode);
EligibilityClassBenefitBusinessLevelData eligibilityLevelData = new EligibilityClassBenefitBusinessLevelData();
eligibilityClassBenefit.EligibilityClassBenefitBusinessLevelNodes = eligibilityLevelData.ExtractBenefitBusinessLevel(reader);
eclassBene.Add(eligibilityClassBenefit);
}
return eclassBene;
}
catch (Exception e)
{
throw new Exception(e.InnerException.Message + e.InnerException.StackTrace);
}
finally
{
//if (_connection.State == ConnectionState.Open) _connection.Close();
if (reader != null) reader.Close();
_command.Dispose();
}
}
Above is an example of code that has a general exception catch in it, yet when i run this program, it will randomly break and thow and unhandled exception to the application log with a .net runtime error null reference exception.
A little background...this is a console application that runs automatically at midnight on an application server. It executes stored procedures against a different SQL Server 2008 box. We used to get these errors when the connections were dropped by the sql server when doing a mainenace task, that is no longer the case. I need to get a mmore specific error. I don't understand why its bypassing the catch clause and just throwing an unhandled runtime exception. What does this mean? It happens at any number of points of code, not just this one. this is just an example of the last that blew up
While you are catching exception, you are also throwing them out to be handled by the caller. Now, there is no entry point in the code you've posted so it's hard to see what's going on outside this snippet.
However, taking a wild guess, my suggestion for origin of the NullRef exception is where you do this: e.InnerException.Message.
The InnerException property may well be null and that will cause a NullRef exception. That, however, is not the real exception. The real exception, which caused the program to end up in the exception handler is hidden because of the above mistake.
If you want to include the message from the InnerException, first check if it's null or not.
EDIT:
Doing this:
catch (Exception e)
{
throw new Exception(e.InnerException.Message + e.InnerException.StackTrace);
}
Catches any exception and rethrows it out to be handled. If the calling code is not handling exceptions, ie not wrapped the call in a try-catch block, the exception will be treated as unhandled by the runtime.
Actually, there is no point at all to do what you are doing. Don't catch exceptions unless you intend to do something about the problem. What you do here is simply messing up the StackTrace for the caller since you are rethrowing a new exception. If you feel you have to cut in and rethrow for some reason, you should do this:
catch (Exception e)
{
throw new Exception("I have a good reason for interrupting the flow", e);
}
Note that the exception instance is passed in the constructor for the rethrown exception. That will end up as the inner exception.
About your exception strategy, this is also pretty unnecessary:
if (_connection.State == ConnectionState.Open)
reader = _command.ExecuteReader(CommandBehavior.CloseConnection);
else
throw new Exception("Connection Closed");
The ExecuteReader method already throws an InvalidOperationException if the connection is closed which is more specific than your throw of Exception. If you intend to do something about that, catch the more specific exception later on. Now, you're using exceptions as part of your program logic which is not good practice.
Related
Based on this question (What benefit does the new Exception filter feature provide?).
The statement:
Exception filters are preferable to catching and rethrowing because
they leave the stack unharmed. If the exception later causes the stack
to be dumped, you can see where it originally came from, rather than
just the last place it was rethrown.
after doing some testing, I did not see the difference between both, the old and the new, I still see the exception from the place it was rethrown. So, or the information is not confirmed, I don't understand the Exception filters( that is why I am asking), or I am doing it wrong. Can you explaing me why this action filter are an advantage?
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email#domain.com";
}
then:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e) when(e.code == 0)
{
WriteLine("E.code 0");
throw; // <-Line 23
}
catch (FormatException e)
{
WriteLine("cond1 " + e.GetBaseException().Message+" "+e.StackTrace);
throw;
}
catch (Exception e) //when (cond2)
{
Console.WriteLine("cond2! " + e.Message);
throw;
}
Result:
The advantages of exception filtering are more to do with when the filter doesn't match, not when it does match. If you remove all of the catch blocks except for the first one, and change the filter on the first catch block to when(e.code != 0), then the callstack of the exception would indicate it was thrown on line 16.
The old way of implementing this would be as follows:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e)
{
if(e.code != 0)
{
WriteLine("E.code isn't 0");
return;
}
throw;
}
In this case, the call stack will indicate that the exception was thrown at the throw statement, rather than on line 16.
I'll give you a good real world example that I've used it for: deadlock retry loops.
Some APIs are nice and have a specific DeadlockException sort of thing -- others, like SOAP proxies, not quite. When you don't have one, exception filters are great to avoid needing to rethrow.
int retryCount = 0;
while(true)
{
try
{
// do stuff.
break;
}
catch(Exception ex) when(ex.Message == "Deadlock" && ++retryCount < 10)
{
// retry up to 10 times.
continue;
}
}
This saves you from having to throw a wrapper exception if a non-deadlock exception happens, or if the retry limit is hit.
I am trying to get the data from the Sybase database. But when I try to dispose or close the connection it throws the exception SQL Runtime Error ...???. No inner exception, no other details. Here is the code I am trying
try
{
List<Dataclass> lstDataclass = new List<Dataclass>();
using (IDataReader reader = this.ExecuteReader(CommandType.StoredProcedure, Constants.ProcedureName, lstSQLParameter))
{
if (reader != null)
{
while (reader.Read())
{
lstDataclass.Add(ReadData(reader) as Dataclass);
}
}
}//Here is exception is thrown
return lstDataclass ;
}
catch (Exception ex)
{
Logging.CDSLogger.LogEntry(MethodBase.GetCurrentMethod(), ex.Message, TraceEventType.Error);
throw;
}
This code throws the exception as mentioned above the stacktrace for this is as,
at iAnywhere.Data.SQLAnywhere.SAInternalConnection.CheckException(Int32 idEx, Boolean freeConn)
at iAnywhere.Data.SQLAnywhere.SAInternalConnection.ReturnToPool()
at iAnywhere.Data.SQLAnywhere.SAConnectionPool.ReturnConnection(SAInternalConnection connection)
at iAnywhere.Data.SQLAnywhere.SAConnectionPoolManager.ReturnConnection(SAInternalConnection connection)
at iAnywhere.Data.SQLAnywhere.SAConnection.Dispose(Boolean disposing)
at iAnywhere.Data.SQLAnywhere.SAConnection.Close()
at iAnywhere.Data.SQLAnywhere.SADataReader.myDispose(Boolean disposing)
at iAnywhere.Data.SQLAnywhere.SADataReader.myDispose()
at iAnywhere.Data.SQLAnywhere.SADataReader.Close()
at BusinessLayer.BusinessCheckRegisterTable.GetAllDataForNacha(EntityEDIScreenRemittanceExport entityScreenRE) in
And if I remove the using then it runs fine. Even If I try to to Close() the connection the same exception is thrown.This only happens for sybase not any other database.
Any help would be great. If anything confusing or not understandable please feel free to comment.
I have the following code:
public string getFinalCon(string desid) {
string finalConId = null;
try
{
query = "select finalConID from discussions where desid=#did";
com = new SqlCommand(query, con);
com.Parameters.AddWithValue("#did", desid);
con.Open();
sdr = com.ExecuteReader();
while (sdr.Read())
{
if (sdr.GetString(0).Equals("none") == false && sdr.GetString(0)!=null)
{
finalConId = sdr.GetString(0);
break;
}
}
con.Close();
}
catch (Exception)
{
}
return finalConId;
}
As you can see I am catching the "Exception", the global exception. But the problem is that whenever this line finalConId=sdr.GetString(0) is executed, the system throws a System.Data.SqlTypes.SqlNullValueException.
Yes it will surely throw it whenever there is NULL value in the database in the corresponding field. But what I want is that this exception should be caught by the catch block and the function should return the default value of finalConId that is NULL as declared in starting of the function. But this is not happening instead it shows up my error page. I am calling this function like this:
string conid = getFinalCon(Request["id"].ToString());
if (conid == null)
{ /*---some code---*/}
else
{/*---some code---*}
How can I handle this exception?
Don't catch exceptions when you don't need to. The proper way to do this is to test sdr.IsDBNull(0) before calling sdr.GetString(0). If IsDBNull() returns true, then GetString() will throw an exception and you should not call it.
It's also very poor practice to swallow all exceptions without indicating some sort of error. catch { } or catch (Exception) { } should be avoided in almost all cases. If something catastrophic happens (the DB connection goes down, for example) you want to allow that exception to propagate. Otherwise, how is the caller to distinguish between the cases "null value in that column" and "database connection died?"
its better to check value with DBNull.Value or IsDBNull() like this
if (reader.IsDBNull(0) && sdr.GetString(0).Equals("none") == false)
//sdr.GetString(0)!=DBNull.Value)
if you want return null when exception than do like this
string conid;
try
{
conid = getFinalCon(Request["id"].ToString());
}
Catch(Exception ex)
{
conid =null;
}
You get an System.Data.SqlTypes.SqlNullValueException because the program trying to read something is NULL from database. You could fix this by checking if the value is NULL before you read it.
Try the following code:
query = "select finalConID from discussions where desid=#did";
com = new SqlCommand(query, con);
com.Parameters.AddWithValue("#did", desid);
con.Open();
sdr = com.ExecuteReader();
while (sdr.Read())
{
if (sdr.GetString(0).Equals("none") == false && !sdr.IsDBNull(0) )
{
finalConId = sdr.GetString(0);
break;
}
}
con.Close();
enter code here
sdr.IsDBNull(0) will check if the value you want to read is NULL. This gonna fix your error :-)
You can use the following structure inside your 'while' loop (considering if you are using ADO connected based Data Access Layer).
if (reader["X"]is DBNull)
{ a = "N/A";}
else
{ a = reader.GetString(reader.GetOrdinal("X")); }
where X is the name of the alias or row name of your DB and a is the object you are linking that reader to.
one thing to consider, in my example, X is a string.
as you can see, you are handling that specific Null reference.
in my function i am returning a datatable that is returned by method
MyDatatable(sqlQuery, connection ),
but it may generate some exceptions that will threw error can i do something like this
return try {cmn.MyDatatable(qry, con)} catch(Exception ex){null};
i don't want to do this way
DataTable dt =null;
try{
dt = cmn.MyDatatable(qry, con);
}catch().....
return dt==null ? null :dt;
Your syntax is quite wrong. You can do it this way:
try
{
return cmd.MyDatatable(qry, con);
}
catch(Exception ex)
{
return null;
}
Although I doubt you want to swallow all exceptions.
IMO, the best way is to do that :
{
object l_oOutDatatable = null;
try
{
oOutDatable = cmd.MyDatatable(qry, con);
}
catch(Exception e)
{
log.Message(e.ToString);
}
return l_oOutDatatable;
}
You must ALWAYS manage exception, because they must have a good reason to be thrown ;). More over it's consider as a good practice to have a single return in each method.
And in bonus, you can use the ?? keyword : This keyword is meaning to return the value or something else if it's null. as Example : c = a ?? b is similar to this : c = (a!=null) ? a : b;
You should return the exception all the way to the client which is calling this code. It is up to the client to handle the exception.
Remember you should only be catching exceptions where you expect them to occur, such as trying to connect to a db or write a file to disk etc.
You should also make your exception catches as specific as possible to catch a know exception that normally occurs when you get the dataset.
try
{
return cmd.MyDatatable(qry, con);
}
catch(Exception ex)
{
//Log exeption
Throw ex
}
If this is just a check to handle null datatables when they have no results then you should test if they are null or populated. This would be a better solution if it is part of your applications ability to return empty datatables.
var dataTableResult = cmd.MyDatatable(qry, con);
if ( dataTableResult != null)
{
return dataTableResult;
}
return null;
catch (OracleException e)
{
Cursor.Current = Cursors.Default;
_instance = null;
if (e.ErrorCode == -2147483648) // {"ORA-01017: invalid username/password; logon denied"}
{
throw new Exception("Nepravilno ime uporabnika ali geslo");
}
else
{
throw new Exception("Ne morem se povezati na podatkovno bazo. Preveri povezavo!");
}
}
but i always get Unhandled exception. Why?
At the risk of stating the obvious... Because you're not catching the Exception you throw in your catch block? Or, perhaps, something else is being thrown in the try block that isn't an OracleException.
What are you expecting to happen?
Just to be totally clear (to make sure that we're on the same page), an exception that's thrown but never caught will result in an unhandled exception (by definition). Throwing an exception from within a catch block is identical to throwing it from anywhere else; there still needs to be a try-catch somewhere to catch it. For example, this exception will be caught:
try {
throw new Exception("Out of cheese error"); // Caught below
}
catch (Exception) { }
But this one results in a new exception being propogated:
try {
throw new Exception("Out of cheese error"); // Caught below
}
catch (Exception) {
throw new Exception("418: I'm a teapot"); // Never caught
}
And this code catches both exceptions:
try {
try {
throw new Exception("Out of cheese error"); // Caught in inner catch
}
catch (Exception) {
throw new Exception("418: I'm a teapot"); // Caught in outer catch
}
}
catch (Exception e) {
Console.WriteLine(e.Message); // "418: I'm a teapot"
}
Your code does not in anyway swallow an exception. All it does is catch one type of exception and throw another type of exception. If you have an unhandled exception before you write this code, you will still have one after you write it.
--UPDATE --
Referring to your comment to another answer, if you want to display a message and stop executing code then try:-
catch (OracleException e)
{
Cursor.Current = Cursors.Default;
_instance = null;
if (e.ErrorCode == -2147483648) // {"ORA-01017: invalid username/password; logon denied"}
{
MessageBox.Show("Nepravilno ime uporabnika ali geslo");
}
else
{
MessageBox.Show("Ne morem se povezati na podatkovno bazo. Preveri povezavo!");
}
// this exits the program - you can also take other appropriate action here
Environment.FailFast("Exiting because of blah blah blah");
}
I assume you call hierarchy look like this:
Main
|-YourMethod
try {}
catch (OracleException) {throw new Exception("blah blah")}
So you see, the OracleException which occured in YourMethod is being caught by catch block, but then you throw a new one which goes into Main, where nothing handles it. So you should add an exception handler on the previous level.
Also, do not hide the original OracleException, throw your exception this way throw new Exception("your message", e). This will preserve the call stack.
Because you're only handling the OracleException. Nothing is handling the Exception() you are throwing.
You're catching the OracleException which means you're prepared to handle it - what does handling it mean to you? Logging it and moving on? Setting some state and moving on? Surely, you don't want to pop up gui in a data access component right? If you're not prepared to handle it, let it bubble up and handle it at an outer layer.
You also shouldn't throw exceptions of type Exception. Create your own strongly typed exceptions so they can be handled, or, simply log and call throw; which rethrows the original.
If you throw a new type of exception ensure you're passing the original exception as the inner exception to ensure you're not hiding details.
I did a write up on some best practices with C# exceptions:
Trying to understand exceptions in C#
Hope that helps