Ошибка согласования: Были ли у кого-нибудь проблемы с сокращенными сообщениями об ошибках?

Я снова здесь, чтобы попросить о помощи. На этот раз я полагаю, что немногие ответят, учитывая большую особенность проблемы, о которой я расскажу. Я начинаю в мире 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 не усекает сообщение. Все в юникоде. Все строки - WideString (по умолчанию) как в моей программе, так и в ZeosLib.

Как вы знаете, для отправки на сервер исключение пересылается клиенту, грубо говоря, DataSnap, а на клиенте метод Reconcile TClientDataSet проверяет, были ли проблемы, а затем генерирует известное исключение EReconcileError это может быть обработано в событии OnReconcileError TClientDataSet, поэтому я считаю, что сообщение усекается DataSnap.

На клиенте я отлаживаю метод согласования (DBClient.pas), и непосредственно перед созданием исключения поток входит в функцию в исходном коде cpp, которая, как мне кажется, является частью библиотеки midas.dll, точнее MidasLib.obj, поскольку я использую эту стратегию, мне не нужно распространять DLL вместе с моим приложением.

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

Этот вызов выполняется в строке 1952 модуля DBClient.pas в Delphi XE Update1.Нажав 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 символ) пробелом (один символ), вы увидите, что строка содержит ровно 255 символов !!

Я также обнаружил, что «GetErrorString» в dspickle.cpp использует константу DBIMAXMSGLEN, которая определена в bdetypes.h как 127 (половина от 255). Поскольку мы находимся в мире Unicode, не стоит ли увеличивать это значение до 255, чтобы иметь два байта на символ? Это только предположение ...

Я оставляю этот вопрос в воздухе, потому что мне не хватает знаний, чтобы понять C ++ :) Кто может помочь, просто посмотрите на реализацию функции "GetErrorString" в dspickle.cpp. Вот это:

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

pString - это сообщение об ошибке, а DBIMAXMSGLEN = 127.

7
задан Carlos Feitoza Filho 2 January 2012 в 14:01
поделиться