Dealing with exceptions in Postgresql implementation
Posted: 28.01.2010, 16:13
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:
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 .
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;
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 .