Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Application Exception happens instead of FbException when Firebird service is stopped. [DNET324] #335

Closed
firebird-automations opened this issue Jun 9, 2010 · 4 comments

Comments

@firebird-automations
Copy link

Submitted by: @luronumen

Votes: 1

ACTUAL RESULT: Application Exception happens instead of FbException when Firebird service is stopped.

EXPECTED RESULT: An FbException should happen instead of Application Exception.

STEPS TO REPRODUCE THIS ISSUE:
1- Start Firebird service and connect with a database [fbConnection].
2- Execute a valid data reader [fbCommand.ExecuteReader()] or Non Query [fbCommand.ExecuteNonQuery()]:
Verify that no error happens;
3- Stop Firebird Service and repeat the same procedure from step 2
ISSUE: An application exception happens instead of an FbException:

***************************************************************************************************************
System.NullReferenceException: Object reference not set to an instance of an object.
at FirebirdSql.Data.Client.Managed.Version10.GdsTransaction.BeginTransaction(TransactionParameterBuffer tpb)
at FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.BeginTransaction(TransactionParameterBuffer tpb)
at FirebirdSql.Data.FirebirdClient.FbTransaction.BeginTransaction()
at FirebirdSql.Data.FirebirdClient.FbCommand.Prepare(Boolean returnsSet)
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior, Boolean returnsSet)
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior)
at FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteNonQuery()
***************************************************************************************************************
Example:

try
{
FbCommand fbCommand = new FbCommand(cmdText, fbConnection);
fbCommand.CommandType = CommandType.Text;
FbDataReader fbDataReader = fbCommand.ExecuteReader();
return fbDataReader;
}
catch (FbException ex)
{
/*THIS EXCEPTION SHOULD GET HERE*/
if (ex.Errors[ex.Errors.Count - 1].Number == 335544726)
MessageBox.Show("Connection to Server Lost.", "ERROR");
}

ENVIRONMENT
- http://ADO.NET Data Provider Version: 05-Jun-2010 19:07 - http://netprovider.cincura.net/FirebirdSql.Data.FirebirdClient.dll;
- Windows 7 Ultimate;
- Microsoft Visual C#⁠ 2010 Express;
- Firebird 2.5.0.25920 Release candidate 2;

Commits: f3c3e35

@firebird-automations
Copy link
Author

Commented by: A. Murat Ozdemiray (ozdemiray)

I have the same problem for 2.6.5 version.

I think Issues DNET291 and DNET401 have the similar problem. Their service is stopped somehow (i.e. server computer might have slept etc.)

@firebird-automations
Copy link
Author

Commented by: A. Murat Ozdemiray (ozdemiray)

I analyzed the problem by debugging from 2.7.0 source code.

GdsTransaction.BeginTransaction method calls GdsDatabase.ReadGenericResponse method (line 152) which returns null to "response" variable. Then BeginTransaction method tries to use this "response" variable which causes a NullReferenceException.

To go deeper in the call stack, ReadGenericResponse method reads an unexpected operation code from XdrStream.ReadOperation method, which eventually calls XdrStream.ReadBytes method returns which could read nothing from the underlying stream but returns successfully as if it read something, because first call to Read method returns 0 and loop do not continue to run, since currentlyRead = 0. So although nothing is read from the stream, the method returns the empty buffer (which is full of 0s).

public byte[] ReadBytes(int count)
{
byte[] buffer = new byte[count];
int toRead = count;
int currentlyRead = -1;
while (toRead > 0 && currentlyRead != 0)
{
toRead -= (currentlyRead = this.Read(buffer, count - toRead, toRead));
}
return buffer;
}

In order to fix the problem in my case, I added following lines to before the return statement;

if(toRead > 0 && toRead == count)
{
throw new InvalidOperationException("Read operations are not allowed by this stream");
}

and InvalidOperationException is catched in GdsTransaction.BeginTransaction method

@firebird-automations
Copy link
Author

Modified by: @cincuranet

status: Open [ 1 ] => In Progress [ 3 ]

@firebird-automations
Copy link
Author

Modified by: @cincuranet

status: In Progress [ 3 ] => Resolved [ 5 ]

resolution: Fixed [ 1 ]

Fix Version: 2.7-next [ 10462 ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants