-1

I have a client/server app developed in delphi XE that uses TIdTcpClient (Indy10) to communicate to each other. All works fine most the time, the only issue is when I kill the server side the client is raising an exception that somehow raises all the way to the user, it first show my custom exception:

enter image description here

and after it display an error dialogue in blank as below:

enter image description here

This is the code that should override the original exception, the dialog I create display and the other dialog (the image above) display just after.

constructor EtvdNTierTcpException.Create(const AException: Exception);
const
 error = 'error message';

var
  AIdSocketError: EIdSocketError;
  sMessage, sConnectionPoint: string;
begin
  if AException is EIdSocketError then
  begin
    AIdSocketError := AException as EIdSocketError;
    if StvdDefaultSession.tvdConnectionPoint = cpSqlProxy then
      sConnectionPoint := FtvdNTierSqlProxy
    else
      sConnectionPoint := FtvdNTierSqlServer;
    case AIdSocketError.LastError of
      // 10054: Connection reset by peer
      10054: self.Message := ExtractFileName(application.exename) + error +  DateToStr(Now) + ' ' + TimeToStr(Now) + ' (' + AIdSocketError.ClassName + ')' + 'Connection for dataset fail at(10054)';
      // 10061: Connection refused
      10061: self.Message := ExtractFileName(application.exename) + error +  DateToStr(Now) + ' ' + TimeToStr(Now) + ' (' + AIdSocketError.ClassName + ')' + 'Connection for dataset fail at(10061)';
      else
        self.Message := error +  DateToStr(Now) + ' ' + TimeToStr(Now) + ' (' + AIdSocketError.ClassName + ')' + 'Connection for dataset fail at('+IntToStr(AIdSocketError.LastError)+')';
    end;
  end;
  inherited;
end;

I try to use CheckForGraceFulDisconnect(false); but it does not make any difference, any ideas in how to stop Indy displaying this error?

This is how the exception above get raised:

function TtvdNTierDataSet.tvdStmtExecute(const AStmt: string): Boolean;
begin
  try
      tvdStmtExecute := False;
      // check we are still connected to the server
      if tvdSession.tvdConnect then
      begin
        tvdStmtExecute := True;
        // write the SQL Statement to the server
        tvdWriteOutput;
      end;
  except
    on E: Exception do
    begin
      // re-raise the exception
      raise EtvdNTierTcpException.Create(E);
    end;
  end;
end;
Icaro
  • 14,585
  • 6
  • 60
  • 75
  • You should not override original code. Do you use TCPClient in the main thread? You should use separate thread. Finally, have you tried try/except for the TCPClient operations? You should catch any exception with that. – smooty86 Jun 16 '15 at 07:08
  • 2
    You did not show where `EtvdNTierTcpException.Create()` is being called from, or in what code the original exception is being raised from. Indy does not raise an exception on disconnect until the next time the underlying socket is accessed. And modifying the original exception is usually the wrong thing to do. Assuming `EtvdNTierTcpException` is an `Exception` descendant, consider using a `try/except` that catches the original exception and use `Exception.RaiseOuterException()` to raise your own exception that captures the original exception as its `InnerException` without modifying it. – Remy Lebeau Jun 16 '15 at 17:06
  • @RemyLebeau is is called when an exception is raised by Indy, I catch the exception and raise this one instead – Icaro Jun 17 '15 at 01:38
  • 1
    @Icaro: Then why are you modifying the original `EIdSocketError` at all? Raising your own exception will simply discard the previous exception, since you are capturing it (or are you? You still did not show the actual code that is raising your exception). – Remy Lebeau Jun 17 '15 at 04:28
  • @RemyLebeau, Sorry I poorly trimmed the function I posted, I fixed it now. I didn't modify the EIdSocketError, I just trap the error and pass it to my own exception that I was expecting would display my message and stop. – Icaro Jun 17 '15 at 04:36
  • 3
    @Icaro: Your exception's constructor is modifying the `Message` property of the original `EIdSocketError` exception, not the `Message` property of your own exception. Leave the original alone. Read from it, do not modify it. Your exception's `Message` is blank, that is why the user is seeing a blank message box. – Remy Lebeau Jun 17 '15 at 08:01
  • 3
    @Icaro: You can optionally capture the original exception into your exception's `InnerException` property if you want exception handlers to have a chance to see the original exception that triggered your exception: `on E: Exception do begin Exception.RaiseOuterException(EtvdNTierTcpException.Create(E)); end;`. – Remy Lebeau Jun 17 '15 at 08:03
  • @RemyLebeau Thanks so much for your help, I modify it, now I have the message in the exception as well, however I don't want this exception to show at all, I just want to show my own exception, but I can't put my head around what I am doing wrong! – Icaro Jun 17 '15 at 22:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/80836/discussion-between-remy-lebeau-and-icaro). – Remy Lebeau Jun 17 '15 at 22:24

1 Answers1

0

if the exception is not of type EIdSocketError you get an empty Exception Dialog.

if AException is EIdSocketError then
FredS
  • 680
  • 1
  • 5
  • 6
  • That is not true, if the exception is not of type EIdSocketError I get the original Exception Dialog, I already test that. – Icaro Jun 28 '15 at 22:19