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

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

мое намерение состоит в том, чтобы сделать диалог согласования ошибок инструментом не только для конечного пользователя, но и для поддержки личных данных, предоставляя отдельно информацию об ошибке, деталях и контексте. Это помогает обнаружить проблему.

теперь проблема заключается в том, чтобы сообщение появилось полностью. У кого-нибудь были такие проблемы с сообщениями, усеченными Мидасом?

также еще один пункт 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.СРР. Есть такое:

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

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

1 ответов


противореча мнению других, я решил настроить дальше и, наконец, понял, как увеличить количество символов в сообщении об ошибке "согласовать". Как я и думал проблема была в Мидас.dll, или, более конкретно, источники, которые составляют Midas dll, потому что тот же набор источников может создать MidasLib, который не требует midas dll. Чтобы решить эту проблему, мне пришлось установить личность Delphi C++ для компиляции midas.

после нахождения строки ошибки, I обнаружил, что есть даже запрос на ремонт КК (http://qc.embarcadero.com/wc/qcmain.aspx?d=84960) который, похоже, был проигнорирован сотрудниками Embarcadero, так как" резолюция "как" отложена до следующего Rel " (отложена до следующего выпуска), но запрос с 2010 года, и я использую Delphi XE, который, на мой взгляд, должен иметь решение, но здесь я исправляю сам ;)

проблема находится внутри метода "клон" класса "DSBASE", внутри источник "ДС.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, который поставляется с Delphi с 2010 года, если я правильно помню. Удачи всем.