trapping 'record changed by another user' errors

Discussion of open issues, suggestions and bugs regarding UniDAC (Universal Data Access Components) for Delphi, C++Builder, Lazarus (and FPC)
Post Reply
hughespa
Posts: 81
Joined: Sat 23 Aug 2008 08:36
Location: W. Australia

trapping 'record changed by another user' errors

Post by hughespa » Wed 21 Apr 2010 08:09

Hi,

Is there a way I can 'globally' trap the above errors (or others for that matter) which may be generated by many different datasets (UniQueries/UniTables)?

I want to add a more descriptive explanation for the end user.

I do a similar thing in the TUniConnection.OnError but that only deals with server side errors according to the documentation.

How can I trap all the 'record changed by another user' errors in a similar way without adding OnUpdateError events to all my datasets?

Regards, Paul.

bork
Devart Team
Posts: 649
Joined: Fri 12 Mar 2010 07:55

Post by bork » Wed 21 Apr 2010 14:50

Hello

Please explain why you cannot use the TUniConnection.OnError event. Can it catch your exception? Or is there any other reason?

hughespa
Posts: 81
Joined: Sat 23 Aug 2008 08:36
Location: W. Australia

Post by hughespa » Thu 22 Apr 2010 02:09

Hi,

Thanks for your reply.

The 'record changed by another user' is firing an EDatabaseError and does not enter the UniConnection.OnError event.

I'm using the ErrorCode in the EDAError passed to the UniConnection.OnError event to determine whether I can display a better 'end user' help message and a hint as to what they might do to rectify the situation if possible. This works well for things like key violations, etc.

I should add D2010, SQL 2008 Express, TUniQuery lockmode is set to optimistic.

Regards, Paul.

bork
Devart Team
Posts: 649
Joined: Fri 12 Mar 2010 07:55

Post by bork » Thu 22 Apr 2010 07:23

Hello

You can use the Application.OnException event to catch all exceptions:

Application.OnException := OnException;

...

procedure TForm1.OnException(Sender: TObject; E: Exception);
begin
if E is EDatabaseError then
ShowMessage(e.Message)
else
Application.ShowException(Exception(E));
end;

hughespa
Posts: 81
Joined: Sat 23 Aug 2008 08:36
Location: W. Australia

Post by hughespa » Thu 22 Apr 2010 07:38

Yes, I do use that for some things but there is no specific UniDAC error number using that method which there is when using the UniConnection.OnError as it is passed the EDAError object with more specific details.

It can be done by parsing the text of the exception message but this is not so good since different providers may generate different text.

With the error numbers it is much cleaner.

Regards, Paul.

bork
Devart Team
Posts: 649
Joined: Fri 12 Mar 2010 07:55

Post by bork » Fri 23 Apr 2010 08:42

TUniError has the ErrorCode property. Why cannot you use it?

hughespa
Posts: 81
Joined: Sat 23 Aug 2008 08:36
Location: W. Australia

Post by hughespa » Fri 23 Apr 2010 09:05

Hi,

I've not heard of TUniError. I can see EUniError exception defined in Uni.pas.

How would I use this, where can I trap this and access it's errorcode? I can't find anything in help about it.

Regards, Paul.

bork
Devart Team
Posts: 649
Joined: Fri 12 Mar 2010 07:55

Post by bork » Fri 23 Apr 2010 12:08

The EUniError is inherited from EDAError. The ErrorCode property is defined in the base class EDAError. You can get the ErrorCode property in the OnError event of TUniSession:

procedure TForm1.UniConnection1Error(Sender: TObject; E: EDAError; var Fail: Boolean);
begin
ShowMessage(IntToStr(E.ErrorCode) + ' - ' + E.Message);
end;

hughespa
Posts: 81
Joined: Sat 23 Aug 2008 08:36
Location: W. Australia

Post by hughespa » Fri 23 Apr 2010 12:18

Yes but the UniConection.OnError event is never fired for 'record changed by another user' exceptions. This was the problem I mentioned in my first post.

e.g. I have this defined

procedure TMainForm.UniDatabaseError(Sender: TObject; E: EDAError; var Fail: Boolean);
begin
case E.ErrorCode of
1222 : //record locked message
2601, 2627 : //key violation message
etc...

but the 'record changed by another user' exception seems to be a simple EDatabaseError. There is no error number available and I cannot trap them all centrally except by using Application.OnException and parsing the text to see if it says 'record changed by another user'.

But if I had an error number it would be cleaner and safer in case the error message text changes in future.

Regards, Paul.

bork
Devart Team
Posts: 649
Joined: Fri 12 Mar 2010 07:55

Post by bork » Mon 26 Apr 2010 09:41

I understand the cause of your requirement. We will investigate the possibility of adding ErrorCode in one of the next builds/versions of the DAC components. Now you can use text comparison because this error message is same for all providers.

hughespa
Posts: 81
Joined: Sat 23 Aug 2008 08:36
Location: W. Australia

Post by hughespa » Mon 26 Apr 2010 11:14

Great. I'll look forward to it and use the text in the meantime.

Thank you.

Regards, Paul.

Post Reply