Can't get OdbcDataAdapter's Fill() method to throw an exception

B

BGU

Hello, I am working on some code to access a legacy data source through
ADO.NET. The legacy vendor has provided us with an ODBC driver. The driver
usually works, but on 20% of trials, it throws an ODBC error. We have
looked into eradicating the error, but concluded that it is not eliminable.
So I need to handle occasional errors in my calling program. So far, so
good.

We know what this ODBC error looks like from writing short JDBC programs to
make it reproduce:

[Legacy Vendor, Inc.][LegacyODBC Driver][ISAM]System error

I figured that under J#, I would be catching a SQLException similar to the
one thrown by JDBC. But I can't get Microsoft's OdbcDataAdapter to
propagate the exception. When I execute the J# code at the bottom of this
post, the program hangs. I assume the cause of the hang is this sequence of
events: (a) the ODBC error occurs, then (b) Microsoft handles it inside one
of the .NET classes rather than propagating it.

Is there some switch I need to toggle in order to get ODBC errors at the
data source to propagate out of the OdbcDataAdapter class as regular
Exceptions? I have already tried adding a FillErrorEventHandler delegate as
a possible solution, but as you can see from

http://msdn.microsoft.com/library/d...atacommondbdataadapterclassfillerrortopic.asp
,

"The FillError event is not returned if the source of the error is generated
at the data source."

Thanks,
Gordon
_________________

package ConsoleApplication1;
import System.Data.Odbc.* ;
import System.Data.* ;
public class Class1
{
public Class1()
{
}

/** @attribute System.STAThread() */
public static void main(String[] args)
{
try
{
OdbcConnection southConnection = new OdbcConnection( "DSN=ACAC" ) ;
OdbcCommand southCommand = new OdbcCommand( "select * from TABLE1",
southConnection ) ;
OdbcDataAdapter southAdapter = new OdbcDataAdapter( southCommand ) ;
southAdapter.add_FillError( new FillErrorEventHandler( handle ) ) ;
System.out.println( southAdapter.get_ContinueUpdateOnError() ) ;
southConnection.Open() ;
DataSet southDataset = new DataSet() ;
System.out.println( southAdapter.Fill( southDataset, "TABLE1" ) ) ;
DataRowCollection rows =
southDataset.get_Tables().get_Item("TABLE1").get_Rows() ;
System.out.println( rows.get_Item( 0 ).get_Item( 0 ) ) ;
}
catch( System.Exception e )
{
System.out.println( e.get_Message() ) ;
}
}
protected static void handle( Object sender, FillErrorEventArgs args )
throws System.Exception
{
args.set_Continue( false ) ;
System.out.println( "Handler is executing." ) ;
System.Exception f = args.get_Errors() ;
throw f ;
}
}
 
W

W.G. Ryan eMVP

I don't see it in the code, but if you're trapping an SqlException - that
won't be thrown by an ODBC object. Try trapping and OdbcException -
although System.Exception should be catching 'everything'

--
W.G. Ryan, MVP

www.tibasolutions.com | www.devbuzz.com | www.knowdotnet.com
BGU said:
Hello, I am working on some code to access a legacy data source through
ADO.NET. The legacy vendor has provided us with an ODBC driver. The
driver usually works, but on 20% of trials, it throws an ODBC error. We
have looked into eradicating the error, but concluded that it is not
eliminable. So I need to handle occasional errors in my calling program.
So far, so good.

We know what this ODBC error looks like from writing short JDBC programs
to make it reproduce:

[Legacy Vendor, Inc.][LegacyODBC Driver][ISAM]System error

I figured that under J#, I would be catching a SQLException similar to the
one thrown by JDBC. But I can't get Microsoft's OdbcDataAdapter to
propagate the exception. When I execute the J# code at the bottom of this
post, the program hangs. I assume the cause of the hang is this sequence
of events: (a) the ODBC error occurs, then (b) Microsoft handles it inside
one of the .NET classes rather than propagating it.

Is there some switch I need to toggle in order to get ODBC errors at the
data source to propagate out of the OdbcDataAdapter class as regular
Exceptions? I have already tried adding a FillErrorEventHandler delegate
as a possible solution, but as you can see from

http://msdn.microsoft.com/library/d...atacommondbdataadapterclassfillerrortopic.asp ,

"The FillError event is not returned if the source of the error is
generated at the data source."

Thanks,
Gordon
_________________

package ConsoleApplication1;
import System.Data.Odbc.* ;
import System.Data.* ;
public class Class1
{
public Class1()
{
}

/** @attribute System.STAThread() */
public static void main(String[] args)
{
try
{
OdbcConnection southConnection = new OdbcConnection( "DSN=ACAC" ) ;
OdbcCommand southCommand = new OdbcCommand( "select * from TABLE1",
southConnection ) ;
OdbcDataAdapter southAdapter = new OdbcDataAdapter( southCommand ) ;
southAdapter.add_FillError( new FillErrorEventHandler( handle ) ) ;
System.out.println( southAdapter.get_ContinueUpdateOnError() ) ;
southConnection.Open() ;
DataSet southDataset = new DataSet() ;
System.out.println( southAdapter.Fill( southDataset, "TABLE1" ) ) ;
DataRowCollection rows =
southDataset.get_Tables().get_Item("TABLE1").get_Rows() ;
System.out.println( rows.get_Item( 0 ).get_Item( 0 ) ) ;
}
catch( System.Exception e )
{
System.out.println( e.get_Message() ) ;
}
}
protected static void handle( Object sender, FillErrorEventArgs args )
throws System.Exception
{
args.set_Continue( false ) ;
System.out.println( "Handler is executing." ) ;
System.Exception f = args.get_Errors() ;
throw f ;
}
}
 
B

BGU

I'm afraid catching OdbcException rather than System.Exception didn't help.

I noticed today that changing the connection string to a non-existent data
source causes an OdbcException to fire like a champ. So it's looking less
like Microsoft is intentionally handling the exception internally and more
like the data adapter is hanging unexpectedly when this particular ODBC
error takes place.

Perhaps there is a bug in OdbcDataAdapter. Or OdbcDataAdapter doesn't work
very well with this ODBC driver. When the ODBC error takes place, the
Microsoft code is hanging instead of throwing an exception.

The ODBC error propagates OK with other access methods (Sun's JDBC-ODBC
bridge). So the overall conclusion *might* be that using data adapters
rather than DataCommand objects is a bad choice when intermittent ODBC
errors are expected. Maybe someone in Redmond can verify or disconfirm this
for the rest of the group.

-Gordon

W.G. Ryan eMVP said:
I don't see it in the code, but if you're trapping an SqlException - that
won't be thrown by an ODBC object. Try trapping and OdbcException -
although System.Exception should be catching 'everything'

--
W.G. Ryan, MVP

www.tibasolutions.com | www.devbuzz.com | www.knowdotnet.com
BGU said:
Hello, I am working on some code to access a legacy data source
through ADO.NET. The legacy vendor has provided us with an ODBC driver.
The driver usually works, but on 20% of trials, it throws an ODBC error.
We have looked into eradicating the error, but concluded that it is not
eliminable. So I need to handle occasional errors in my calling program.
So far, so good.

We know what this ODBC error looks like from writing short JDBC programs
to make it reproduce:

[Legacy Vendor, Inc.][LegacyODBC Driver][ISAM]System error

I figured that under J#, I would be catching a SQLException similar to
the one thrown by JDBC. But I can't get Microsoft's OdbcDataAdapter to
propagate the exception. When I execute the J# code at the bottom of
this post, the program hangs. I assume the cause of the hang is this
sequence of events: (a) the ODBC error occurs, then (b) Microsoft handles
it inside one of the .NET classes rather than propagating it.

Is there some switch I need to toggle in order to get ODBC errors at the
data source to propagate out of the OdbcDataAdapter class as regular
Exceptions? I have already tried adding a FillErrorEventHandler delegate
as a possible solution, but as you can see from

http://msdn.microsoft.com/library/d...atacommondbdataadapterclassfillerrortopic.asp ,

"The FillError event is not returned if the source of the error is
generated at the data source."

Thanks,
Gordon
_________________

package ConsoleApplication1;
import System.Data.Odbc.* ;
import System.Data.* ;
public class Class1
{
public Class1()
{
}

/** @attribute System.STAThread() */
public static void main(String[] args)
{
try
{
OdbcConnection southConnection = new OdbcConnection( "DSN=ACAC" ) ;
OdbcCommand southCommand = new OdbcCommand( "select * from TABLE1",
southConnection ) ;
OdbcDataAdapter southAdapter = new OdbcDataAdapter( southCommand ) ;
southAdapter.add_FillError( new FillErrorEventHandler( handle ) ) ;
System.out.println( southAdapter.get_ContinueUpdateOnError() ) ;
southConnection.Open() ;
DataSet southDataset = new DataSet() ;
System.out.println( southAdapter.Fill( southDataset, "TABLE1" ) ) ;
DataRowCollection rows =
southDataset.get_Tables().get_Item("TABLE1").get_Rows() ;
System.out.println( rows.get_Item( 0 ).get_Item( 0 ) ) ;
}
catch( System.Exception e )
{
System.out.println( e.get_Message() ) ;
}
}
protected static void handle( Object sender, FillErrorEventArgs args )
throws System.Exception
{
args.set_Continue( false ) ;
System.out.println( "Handler is executing." ) ;
System.Exception f = args.get_Errors() ;
throw f ;
}
}
 
W

W.G. Ryan eMVP

BGU - I'm not sure but it really does sound like it's hanging and not that
the exception is just being eaten. I'll see what I can find out and report
back.

--
W.G. Ryan, MVP

www.tibasolutions.com | www.devbuzz.com | www.knowdotnet.com
BGU said:
I'm afraid catching OdbcException rather than System.Exception didn't
help.

I noticed today that changing the connection string to a non-existent data
source causes an OdbcException to fire like a champ. So it's looking less
like Microsoft is intentionally handling the exception internally and more
like the data adapter is hanging unexpectedly when this particular ODBC
error takes place.

Perhaps there is a bug in OdbcDataAdapter. Or OdbcDataAdapter doesn't
work very well with this ODBC driver. When the ODBC error takes place,
the Microsoft code is hanging instead of throwing an exception.

The ODBC error propagates OK with other access methods (Sun's JDBC-ODBC
bridge). So the overall conclusion *might* be that using data adapters
rather than DataCommand objects is a bad choice when intermittent ODBC
errors are expected. Maybe someone in Redmond can verify or disconfirm
this for the rest of the group.

-Gordon

W.G. Ryan eMVP said:
I don't see it in the code, but if you're trapping an SqlException - that
won't be thrown by an ODBC object. Try trapping and OdbcException -
although System.Exception should be catching 'everything'

--
W.G. Ryan, MVP

www.tibasolutions.com | www.devbuzz.com | www.knowdotnet.com
BGU said:
Hello, I am working on some code to access a legacy data source
through ADO.NET. The legacy vendor has provided us with an ODBC driver.
The driver usually works, but on 20% of trials, it throws an ODBC error.
We have looked into eradicating the error, but concluded that it is not
eliminable. So I need to handle occasional errors in my calling program.
So far, so good.

We know what this ODBC error looks like from writing short JDBC programs
to make it reproduce:

[Legacy Vendor, Inc.][LegacyODBC Driver][ISAM]System error

I figured that under J#, I would be catching a SQLException similar to
the one thrown by JDBC. But I can't get Microsoft's OdbcDataAdapter to
propagate the exception. When I execute the J# code at the bottom of
this post, the program hangs. I assume the cause of the hang is this
sequence of events: (a) the ODBC error occurs, then (b) Microsoft
handles it inside one of the .NET classes rather than propagating it.

Is there some switch I need to toggle in order to get ODBC errors at the
data source to propagate out of the OdbcDataAdapter class as regular
Exceptions? I have already tried adding a FillErrorEventHandler
delegate as a possible solution, but as you can see from

http://msdn.microsoft.com/library/d...atacommondbdataadapterclassfillerrortopic.asp ,

"The FillError event is not returned if the source of the error is
generated at the data source."

Thanks,
Gordon
_________________

package ConsoleApplication1;
import System.Data.Odbc.* ;
import System.Data.* ;
public class Class1
{
public Class1()
{
}

/** @attribute System.STAThread() */
public static void main(String[] args)
{
try
{
OdbcConnection southConnection = new OdbcConnection( "DSN=ACAC" ) ;
OdbcCommand southCommand = new OdbcCommand( "select * from TABLE1",
southConnection ) ;
OdbcDataAdapter southAdapter = new OdbcDataAdapter( southCommand ) ;
southAdapter.add_FillError( new FillErrorEventHandler( handle ) ) ;
System.out.println( southAdapter.get_ContinueUpdateOnError() ) ;
southConnection.Open() ;
DataSet southDataset = new DataSet() ;
System.out.println( southAdapter.Fill( southDataset, "TABLE1" ) ) ;
DataRowCollection rows =
southDataset.get_Tables().get_Item("TABLE1").get_Rows() ;
System.out.println( rows.get_Item( 0 ).get_Item( 0 ) ) ;
}
catch( System.Exception e )
{
System.out.println( e.get_Message() ) ;
}
}
protected static void handle( Object sender, FillErrorEventArgs args )
throws System.Exception
{
args.set_Continue( false ) ;
System.out.println( "Handler is executing." ) ;
System.Exception f = args.get_Errors() ;
throw f ;
}
}
 
Top