gpt4 book ai didi

delphi - 协调错误: Has anyone had problems with truncated error messages?

转载 作者:行者123 更新时间:2023-12-03 14:53:30 24 4
gpt4 key购买 nike

我又来找你帮忙了。这次我相信,鉴于我将涉及的问题的特殊性,很少有人会做出回应。我刚开始进入 DataSnap 的世界,但仍然有些事情我不明白这个错误如何关联。

我的 Delphi 是 XE(版本 1,Update1)。我正在使用 Postgres,它会生成葡萄牙语(巴西葡萄牙语)的错误消息,因此错误消息带有重音。连接组件是ZeosLib包。

我正在使用“协调错误”对话框来显示更新应用程序产生的错误,并进行测试,我尝试插入已存在的记录,从而违反了唯一键并显示协调错误对话框。

在对话框的备忘录中,出现的消息被截断,即剪切。检查一下:

ERRO:  duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"
DETAIL: Chave (va_login)=(admin) já existe.
CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME
,VA_LOGIN
,CH

但实际上应该返回的是:

ERRO:  duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"
DETAIL: Chave (va_login)=(admin) já existe.
CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME
,VA_LOGIN
,CH_SENHA
,VA_EMAIL)
VALUES (pVA_NOME
,pVA_LOGIN
,pCH_SENHA
,pVA_EMAIL)"
PL/pgSQL function "idu_usuarios" line 7 at comando SQL

我在服务器上做了调试,看看问题是否出在ZeosLib上,但我发现服务器上生成的错误消息是完整的,证明ZeosLib没有截断消息。一切都是unicode。在我的程序和 ZeosLib 中,所有字符串都是 WideString(默认)。

如你所知,要在服务器上抛出异常,粗略地说,是通过DataSnap将异常转发到客户端,而在客户端上,TClientDataSet的Reconcile方法验证是否存在问题,然后抛出著名的异常EReconcileError可以在 TClientDataSet 的 OnReconcileError 事件中处理,因此我相信该消息正在被 DataSnap 截断。

在客户端上,我调试 Reconcile 方法 (DBClient.pas),并且在抛出异常之前,流程立即进入 cpp 源代码中的一个函数,我认为该函数是 midas.dll 库的一部分,更具体地说,是 MidasLib.obj,因为我使用这种策略,所以不必将 DLL 与我的应用程序一起分发。

Check(FDSBase.Reconcile_MD(FReconcileDataSet.FDSBase, FDeltaPacket, VarToDataPacket(Results), Integer(Self), RCB));

此调用在 Delphi XE Update1 上的 DBClient.pas 单元的第 1952 行完成。按 F7,调试器会输入源 C++ (cpp),因此我相信它位于 midaslib.obj 内。我对 C++ 不太了解,我按 Shift-F8 退出当前方法并返回下一条指令,该指令已经在事件 OnReconcileError 中了!因此,截断必须在我提到的函数内、cpp 源代码内、midaslib 内完成。

我的目的是使“协调错误”对话框不仅成为最终用户的工具,而且成为支持个人的工具,分别提供错误、详细信息和上下文的信息。这对于发现问题有很大帮助。

现在的问题是让消息完整​​显示。有人遇到过这种消息被 midas 截断的问题吗?

还有一点 DSClient.pas 我可以在传递给异常时提取错误消息:

'Erro SQL: ERRO:  duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"'#$A'DETAIL:  Chave (va_login)=(admin) já existe.'#$A'CONTEXT:  comando SQL "INSERT INTO USUARIOS (VA_NOME'#$A'                           ,VA_LOGIN'#$A'                           ,CH'

如果删除引号并将#$A(1 个字符)替换为空格(1 个字符),您将看到该字符串正好有 255 个字符!!

我还发现 dspickle.cpp 中的“GetErrorString”使用常量 DBIMAXMSGLEN,该常量在 bdetypes.h 中定义为 127(255 的一半)。由于我们身处 Unicode 世界,因此将这个值增加到 255 以便每个字符有两个字节不是一个问题吗?这只是一个猜测...

我把这个问题悬而未决,因为我缺乏理解C++的知识:)谁能帮忙,看看dspickle.cpp中的函数实现“GetErrorString”。有这样的:

LoadString((HINSTANCE)hDll, iErrCode, pString, DBIMAXMSGLEN)

pString 是错误消息,DBIMAXMSGLEN = 127。

最佳答案

与其他人的意见相矛盾,我决定进一步调整,并最终弄清楚如何增加“协调”错误消息中的字符数。我认为问题出在 midas.dll 中,或者更具体地说,问题出在构成 midas dll 的源中,因为同一组源可以创建 MidasLib,它不需要 midas dll。为了解决这个问题,我必须安装 Delphi C++ 个性来编译 midas。

找到错误行后,我发现甚至有一个对QC ( http://qc.embarcadero.com/wc/qcmain.aspx?d=84960 ) 进行维修的请求,但似乎被Embarcadero 的工作人员忽略了,因为“解决方案”是“推迟到下一个版本”(推迟到下一个版本),但请求是从 2010 年开始的,我正在使用 Delphi XE,我认为它应该有解决方案,但在这里我自己更正;)

问题出在“DSBASE”类的“Clone”方法内部,位于源“ds.cpp”第 2133 行(Delphi XE,Update1)。下面是代码块。红线是有问题的线:

// Set the third field for the error string.
LdStrCpy((pCHAR)pFldDes->szName, szdsERRMESSAGE);
pFldDes->iFldType = fldZSTRING;
pFldDes->iUnits1 = 255; // Increased on request.. DBIMAXMSGLEN;
pFldDes++;

请注意,问题线非常有趣。它的常量值为 255,它限制错误消息的大小和注释“根据请求增加”。另请注意,注释旁边有一个常量 DBIMAXMSGLEN,我发现它并且已经怀疑它是导致问题的原因,但由于它没有被使用,所以我更改了 的值DBIMAXMSGLEN 但错误消息始终没有更改。值得一提的是,DBIMAXMSGLEN 之后有一个分号 (;),这让我认为在之前(我不知道什么时候)这一行是我修复之后的一行:

pFldDes->iUnits1 = DBIMAXMSGLEN;

就好像有人故意将字段值设置为 255,从而删除了之前真正动态且看似更正确的实现。执行该行的替换后,我将 DBIMAXMSGLEN 的值增加到 1024。DBIMAXMSGLEN 被声明为“bdetypes.h”作为定义。更正后,该行如下所示:

#define DBIMAXMSGLEN         1024           // Max message len

在“ds.cpp”和“bdetypes.h”中进行这两项更改后,我进行了构建、测试,结果符合预期:错误消息在“协调”对话框中完整呈现。

对于那些想尝试的勇敢者,如果他们遇到过这个问题,你需要MIDAS的源代码,如果我没记错的话,MIDAS是从2010年开始随Delphi一起提供的。祝大家好运。

关于delphi - 协调错误: Has anyone had problems with truncated error messages?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8701752/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com