Disposing the IDataReader giving Runtime Error? - c#

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.

Related

MVC SQL connection initialization

I am working on a MVC web page that edits a SQL DB table. In my controller, I have a DB call to increment an entity table. Then if successful, creates a new row in my target table (not the entity table).
The problem I am running into is I keep getting the following error:
The ConnectionString property has not been initialized.
However this only happens after the entity table has been incremented. Not sure where to go on this, so I am hoping that by posting some code, someone would be able to help me find my error.
so here is the obligatory code:
My SQL Connection:
private SqlConnection con;
public BaseRepository()
{
con = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlServerConnection"].ToString());
}
My Entity Table Increment Call:
public int GetNextId()
{
try
{
using (con)
{
DynamicParameters dynParam= new DynamicParameters();
dynParam.Add("#entity_name", "insert_object ");
con.Open();
var value = con.Execute(SP_GET_NEW_ID, dynParam, commandType: CommandType.StoredProcedure);
con.Close();
return value;
}
}
catch (Exception ex) { throw ex; }
}
Finally, here is the Row Insert Code:
public int InsertRowCode(InsertObject ccModel, UserModel appUser)
{
var value = GetNextId();
if (value == 1)
{
try
{
using (con)
//this is where the code breaks and jumps the the exception ex in my catch
{
con.Open();
var dP = new DynamicParameters();
//(add 14 dynamic Parameters here)
var result = con.Execute(SP_SAVE_CORRECTION_CODES, dP, commandType: CommandType.StoredProcedure);
con.Close();
return result;
}
}
catch (Exception ex)
{
throw ex;
}
}
else { throw new Exception("Busted"); }
}
Any help is greatly appreciated. TIA
Don't use shared connection objects.
When you exit this block:
using (con)
{
//...
}
That connection object is now disposed and can't be used anymore. Don't worry about trying to optimize your connections, the connection pool does a very good job of that already. Create your connection objects where you need them, use them, and dispose them in a tight scope:
using (var con = new SqlConnection(connectionString))
{
//...
}
As a side note, this is superfluous:
catch (Exception ex)
{
throw ex;
}
That catch block isn't doing anything for you, and is actually deleting important information about the exception. Just remove that try/catch entirely.
If, on the other hand, you ever do want to do something with an exception before re-throwing it, just use the keyword throw by itself:
catch (Exception ex)
{
// log something, etc.
throw;
}
This would allow the exception to continue up the stack unmodified, preserving the actual error information.

Closing An SqlDataReader that might not have been initialized

I'm stuck in a cycle of different compiler errors and I need some assistance.
So case 1: SqlDataReader executed outside of try block allows closing it later, however, leaves the reader exceptions unhanded.
var cmd = String.Format("SQL COMMAND HERE");
var command = new SqlCommand(cmd, conSQL);
SqlDataReader readerSql = command.ExecuteReader(); //Unhandled Exceptions here
try
{
while (readerSql.Read())
{....}
}
catch (SqlException e)
{...}
finally
{
readerSql.Close(); //Compiler error: Might not have been initialized
}
Case 2: Reader is executed inside try block, reader exceptions can be handled, however, reader cannot be closed on exceptions.
SqlDataReader readerSql;
try{
readerSql = command.ExecuteReader();
while (readerSql.Read())
{...}
readerSql.Close(); //Does not close on exceptions
}
catch (SqlException e)
{
readerSql.Close(); //Compiler error: Might not have been initialized
}
finally
{
if(readerSql != null) //Compiler Error on if statement, same as below
readerSql.Close(); //Compiler error: Might not have been initialized
}
Use the using statement, it solves your issue:
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object.
As Alioza says the best method is the using statement.
using (var readerSql = command.ExecuteReader()) {
while (readerSql.Read()) {
{....}
}
}
https://msdn.microsoft.com/en-us/library/yh598w02.aspx (using statement documentation)
you can use the using statement and not worry about closing.
using(SqlDataReader readerSql = command.ExecuteReader()){
try{
while (readerSql.Read())
{....}
}
catch (SqlException e)
{
//execption
}
}

Unhandled runtime error c#

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.

C# oracle : catch all exceptions relative to connectivity?

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

ADO.NET Funny Connection Pool Behaviour when bury SQL Exception

I am catching a sql exception and not rethrowing it. This seems to mean that the connection is not returned to the pool as I would expect. Is this possible?
using (IDbCommand paymentCommand = this.Connection.CreateCommand())
{
try
{
//database stuff
}
catch (SqlException ex)
{
//LOG CALL
}
}
why don't you put using(...){} inside try{} block? This way even if exception is thrown, using block will dispose off IDBcmd obj.
It's not clear in your question how you are creating the connection, but you do need to make sure you Open it, then Close it, regardless of errors or not.
Typically I'll do something like this:
SqlConnection connection = null;
try {
connection.Open();
// Do stuff like run a query, setup your IDbCommand, etc.
} catch (Exception ex) {
// Log error
} finally {
if (connection != null) {
connection.Close();
}
}
This way, no matter what happens, your connection will be closed and returned to the pool. If you fail to Close(), you'll "leak" that connection and eventually run out of pooled connections to draw from. The lifetime of the connection should generally only be as long as it takes to issue your sql command, at which point you should be closing it.
It's not clear what you are experiencing with the connection pool. However, I would definitely wrap your connection in a using statement.
This is what I usually use (note that dac.GetConnection() is simply a class that centralizes the code to get a connection object):
using (SqlConnection connection = dac.GetConnection())
{
using (SqlCommand command = new SqlCommand("myProc", connection))
{
command.CommandType = CommandType.StoredProcedure;
try
{
connection.Open();
//add params, run query
}
catch (Exception ex)
{
//handle/log errror
}
finally
{
if (connection.State == ConnectionState.Open)
connection.Close();
}
}
}

Categories

Resources