Page 1 of 1

Dealing with exceptions in Postgresql implementation

Posted: 28.01.2010, 16:13
by Wild_Pointer
Hello

I'm using postgresql and zeos lib v6.6.6.
I noticed that if the connection is lost the exception about that is raised. After that even closing the program generates access violations. I doubt this is normal way of dealing with broken connections :)

I guess the source of all evil is CheckPostgreSQLError in file ZDbcPostgreSqlUtils.pas:

Code: Select all

procedure CheckPostgreSQLError(Connection: IZConnection;
  PlainDriver: IZPostgreSQLPlainDriver;
  Handle: PZPostgreSQLConnect; LogCategory: TZLoggingCategory;
  LogMessage: string;
  ResultHandle: PZPostgreSQLResult);

var ErrorMessage: string;
//FirmOS
    StatusCode:String;
begin
  if Assigned(Handle) then
    ErrorMessage := Trim(StrPas(PlainDriver.GetErrorMessage(Handle)))
  else ErrorMessage := '';
  if ErrorMessage<>'' then begin
    if Assigned(ResultHandle) then begin
{     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SEVERITY)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_PRIMARY)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_DETAIL)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_MESSAGE_HINT)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_STATEMENT_POSITION)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_INTERNAL_POSITION)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_INTERNAL_QUERY)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_CONTEXT)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_FILE)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_LINE)));
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SOURCE_FUNCTION)));
}
     StatusCode := Trim(StrPas(PlainDriver.GetResultErrorField(ResultHandle,PG_DIAG_SQLSTATE)));
    end else begin
     StatusCode:='';
    end;
  end;



  if ErrorMessage <> '' then
  begin
    if Assigned(Connection) and Connection.GetAutoCommit then
      Connection.Rollback;

    DriverManager.LogError(LogCategory, PlainDriver.GetProtocol, LogMessage,      0, ErrorMessage);
    if ResultHandle <> nil then PlainDriver.Clear(ResultHandle);
    if PlainDriver.GetStatus(Handle) = CONNECTION_BAD then
    begin
      PlainDriver.Finish(Handle);
    end;
    raise EZSQLException.CreateWithStatus(StatusCode,Format(SSQLError1, [ErrorMessage]));
  end;
end;
1. It tries to rollback connection that may already be broken.
2. It Closes the connection on libpq side, but does nothing on our side. That creates situation when we order libpq to free connection resources, but in Zeos components we still think everything is ok.

There's nothing changed in Zeos 7 (except after PlainDriver.Finish(Handle); there is Handle := nil; witch is just ignored by compiler as it does nothing).

If someone would advice how the situation should be properly handled I would try to create a patch for it as I hate access violations in my programs :).

Posted: 29.01.2010, 22:32
by mdaems
Hi,

Does the compiler still ignore Handle := nil since rev 760? We made Handle a var parameter at that time. See this thread

Mark

Posted: 31.01.2010, 11:57
by Wild_Pointer
Thank you, Mark.

I've missed the point, that Handle is var parameter now. I just inserted Handle := nil into 6.6.6 version to see if that helps to solve "connection lost" problem, and obviously got negative result.

I'll report problems to the thread you provided.