Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 10 total
Thread Capture EEDBSocketException
Thu, Oct 1 2020 10:01 PMPermanent Link

Ian Branch

Avatar

Hi Team,
I have had a couple of these from my Customer.

Error Type - EEDBSocketException
Error Message - Socket error.  An existing connection was forcibly closed by the remote host. (10054) on API 'recv'.

I suspect their connection is flaky.

How do I catch I catch these, preferably in a a Try Except End structure?
I can see nothing in the EDB Help or Error codes that alludes to a Socket Exception.

Regards & TIA,
Ian
Fri, Oct 2 2020 3:09 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian

It may be hardware (most likely) or firewall or AV. A few extra questions/thoughts:

Is it happening on various PCs?  if so that would suggest the server is at fault.

Is it wired or wireless?  If the latter lots of things can screw it up.

Is it powerline ethernet? Then it could be the power is bad - I get this on my home network where my powerline ethernet to my router can glitch out but the direct wired or wireless PCs are fine.


At this point, never had it happen to me, the only thing I can suggest is using the TEDBSession's disconnect events - probably AfterDisconnect, or possibly the OnRemoteTimeout and testing for the error

There is also global exception handling - from the OLH

Exception Events
Besides trapping exceptions with a try..except or try..catch block, you may also use a global
TApplication.OnException event handler to trap database exceptions. However, doing so will eliminate
the ability to locally recover from the exception and possibly retry the operation or take some other
course of action. There are several events in ElevateDB components that allow you to code event
handlers that remove the necessity of coding try..except or try..catch blocks while still providing for local
recovery. These events are as follows:


Roy Lambert
Fri, Oct 2 2020 1:09 PMPermanent Link

Ian Branch

Avatar

Hi Roy,
The Why of it happening is simple - Poor internet connectivity in Fiji. Frown I can do nothing about that.
It has happened on a couple of PCs now.
That is why I want to capture it and have the Apps exit gracefully rather than throwing a full error.
My problem is I could find no referencxe to EEDBSocketException so I could see how to capture it properly.
I will have a look at TEDBSession's disconnect events.

Regards & Tks,
Ian
Fri, Oct 2 2020 1:50 PMPermanent Link

Raul

Team Elevate Team Elevate

On 10/2/2020 1:09 PM, Ian Branch wrote:
> Hi Roy,
> The Why of it happening is simple - Poor internet connectivity in Fiji. Frown I can do nothing about that.
> It has happened on a couple of PCs now.
> That is why I want to capture it and have the Apps exit gracefully rather than throwing a full error.
> My problem is I could find no referencxe to EEDBSocketException so I could see how to capture it properly.
> I will have a look at TEDBSession's disconnect events.

EEDBSocketException itself is declared in the edbsocket.pas class and is
thrown for pretty much any failure with the winsocket.

'recv' specifically is thrown in "TEDBSocketWrapper.ReceiveStream"
function so that might be bit tricky to capture  - in theory you should
be able to wrap your remote activities (i.e. query open or execute) in
try/except and capture this

There might be other scenarios (i'm thinking hearbeat and such though
i'm guessing here now) where you might not have any  obvious code to
wrap so using session events or systemwide exception handler might be
better.

There is also this article in case you have not seen it with some
suggestions :
https://www.elevatesoft.com/articles?action=view&category=edb&article=connections_disconnections_reconnections

Raul

Fri, Oct 2 2020 5:28 PMPermanent Link

Ian Branch

Avatar

Tks Raul,
>> 'recv' specifically is thrown in "TEDBSocketWrapper.ReceiveStream"
function so that might be bit tricky to capture  - in theory you should
be able to wrap your remote activities (i.e. query open or execute) in
try/except and capture this

This is exactly what I want to do but I don't know what to 'capture' in terms of an error code or similar.

Regards,
Ian
Sat, Oct 3 2020 5:09 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian


I had thought you were talking LAN Frown

If the TEDBSession's disconnect events don't work (I think they should) then trying to determine if you have internet is a major problem. The only way that is totally reliable is to try and connect to somewhere or to ping them. One suggestion would be to spin up a separate thread which is dedicated to pinging the server (which is what the RemotePing property does, and if that's not on turn it on) and passing an error back to the main thread if the ping fails.

Roy Lambert
Sat, Oct 3 2020 5:44 AMPermanent Link

Ian Branch

Avatar

Hi Roy,
That sounds like an option.  Regrettably I have zero idea on how to implement it.
Further, the Help isn't too forthcoming in regard to RemotePing's usage.
What error would be generated if the Ping failed?

Regards,
Ian
Sat, Oct 3 2020 9:19 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Ian

>That sounds like an option. Regrettably I have zero idea on how to implement it.

I do <VBG>

>Further, the Help isn't too forthcoming in regard to RemotePing's usage.

That's cos all you are meant o do is turn it on and say how often.

>What error would be generated if the Ping failed?


** PLEASE NOTE I've never had this happen and no longer run a server so its wild guess time **

RemotePing is meant to keep a connection live and keep the server from timing out so if it fails it means the connection has been lost which should result in a disconnect event being fired.

I think your best bet would be to open a support ticket with Tim - he should know what to do - if not I recommend panic as the way forwards.

Roy
Sat, Oct 3 2020 1:41 PMPermanent Link

Raul

Team Elevate Team Elevate

On 10/2/2020 5:28 PM, Ian Branch wrote:
>
> This is exactly what I want to do but I don't know what to 'capture' in terms of an error code or similar.
>

I took a quick look and EDB only surfaces EEDBError and not socket one
but that should be good enough as 1100 is EDB_ERROR_CLIENTCONN and if
you really want you could parse out Winsock error from that message or
just treat the whole 11or maybe even 11xx block as most of those are
connection based  "connection down".

So something as simple as this should work (i'm checking range here

  try
    myEDBTable.Open;
  except
    on EE:EEDBError do
    begin
      if (EE.ErrorCode >= 1100) and (EE.ErrorCode < 1200) then
      begin
        // looks like connection down so deal with it
        //if you want you could try to parse specific winsock errors
        // if pos('(10054)',EE.Message) > 0 then
        //   ....
      end
      else
      begin
        //some other EEDBError
      end;
    end;
    on E:Exception do
    begin
      //generic error - log just in case maybe
    end;
  end;


As a more generic route under your control is to create a small
"connection tester" routine you can call regularly like from timer or
from your code to check connection is OK in key places. I would use a
server side function (i like GetRemoteDateTime) to ensure you're testing
both connection and edbserver operation in one go.

For example something like this is a super simple example of what i mean
- i try to open connection and get server datetime. Any exception thrown
here would basically indicate problem with connection or server

function TForm1.IsServerConnectionUP: boolean;
begin
  result := false;
  try
    if not MyEDBSession.Connected then
      MyEDBSession.Connected := true;
    MyEDBSession.GetRemoteDateTime;
    result := true; //if we got here no exception was thrown
  except
  end;
end;



Raul
Sat, Oct 3 2020 5:11 PMPermanent Link

Ian Branch

Avatar

Tks Raul,
For now this is what I have implemented..
{code}
procedure TMainForm.SessionsTimer(Sender: TObject);
begin
 //
 try
   //
   begin
     tsDBiSessions.Close;
     tsDBiSessions.SQL.Clear;
     tsDBiSessions.SQL.Text := 'Select SessionCount from DBiSessions';
     tsDBiSessions.ExecSQL;
     nSessionCount := tsDBiSessions.FieldByName('SessionCount').AsInteger;
     tsDBiSessions.Close;
     lblSessions.Caption := nSessionCount.ToString + ' of ' + nLicensedSessions.ToString + ' licensed sessions in use at this time.';
   end;
 except
   on EE: EEDBError do
   begin
     MessageBeep(MB_ICONERROR);
     if (EE.ErrorCode >= 1100) and (EE.ErrorCode < 1200) then
       ShowMessage('It looks like the Connection to the Database Server has been lost!')
     else
       ShowMessage('Unknown or unexpected database engine error # ' + EEDBError(EE).ErrorCode.ToString);
   end;
   on E: Exception do
   begin
     ShowMessage('Unknown or unexpected error has occurred');
   end;
   //
 end;
 //
end;
{code}

SessionsTimer runs every 60 seconds to update the Sessions caption.

I will see how this goes.

Regards & Tks again,
Ian
Image