Estoy aquí nuevamente para pedirte ayuda. Esta vez creo que pocos responderán dada la gran particularidad del problema que relataré. Estoy comenzando en el mundo de DataSnap, y todavía tengo cosas que no entiendo cómo relacionaré este error.Reconcile Error: ¿Alguien ha tenido problemas con los mensajes de error truncados?
Mi Delphi es XE (versión 1, actualización 1). Estoy usando Postgres que genera mensajes de error en portugués (portugués de Brasil) y por esta razón los mensajes de error tienen acentos. Los componentes de conexión son paquete ZeosLib.
Estoy usando un cuadro de diálogo "reconciliar error" para mostrar errores derivados de la aplicación de actualizaciones y para probar, traté de insertar un registro que ya existía, violando así una clave única y mostrando así el cuadro de diálogo de error de conciliación.
En la nota del cuadro de diálogo, el mensaje que aparece se trunca, es decir, se corta. Compruébelo usted mismo:
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
Pero en realidad lo que debe ser devuelta es la siguiente:
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
he hecho una depuración en el servidor para ver si el problema es ZeosLib, pero me encontré con que el mensaje de error generado en el servidor está completo, lo que demuestra que ZeosLib no trunca el mensaje. Todo es unicode Todas las cadenas son WideString (por defecto) tanto en mi programa como en ZeosLib.
Como usted sabe, para lanzarse al servidor, la excepción se reenvía al cliente, en términos generales, por DataSnap, y en el cliente, el método Reconciliar de TClientDataSet verifica si hubo problemas y luego lanza la famosa excepción EReconcileError que se puede manejar en el evento OnReconcileError de TClientDataSet, por lo tanto, creo que el mensaje está siendo truncado por DataSnap.
En el cliente, debo depurar el método Reconcile (DBClient.pas) e inmediatamente antes de que se produzca la excepción, el flujo entra en una función dentro de un código fuente cpp que creo que forma parte de la biblioteca midas.dll, MidasLib.obj más específicamente , ya que estoy usando esta estrategia, no tengo que distribuir el archivo DLL con mi aplicación.
Check(FDSBase.Reconcile_MD(FReconcileDataSet.FDSBase, FDeltaPacket, VarToDataPacket(Results), Integer(Self), RCB));
Esta llamada se realiza en la línea 1952 de los DBClient.pas unidad de Delphi XE Update1. Presionando F7, el depurador ingresa una fuente C++ (cpp), así que creo que está dentro de midaslib.obj. Como no entiendo bien C++, presiono Shift-F8 para salir del método actual y devolver la siguiente instrucción, que ya está dentro del evento OnReconcileError !! Por lo tanto, el truncamiento debe realizarse dentro de la función que mencioné, dentro de una fuente de cpp, dentro de midaslib.
Mi intención es hacer que el cuadro de diálogo Reconciliar error sea una herramienta no solo para el usuario final, sino también para dar soporte a los personales, proporcionando por separado información de Error, Detalles y Contexto. Esto ayuda mucho a descubrir un problema.
El problema ahora es hacer que el mensaje aparezca completo. ¿Alguien ha tenido este tipo de problema con mensajes truncados por midas?
también otro punto de DSClient.pas pude extraer el mensaje de error, ya que se pasa a la excepción:
'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'
Si quita las comillas y reemplazar # $ A (1 carácter) por un espacio en blanco (un personaje), verás que la cadena tiene exactamente 255 caracteres.
También descubrí que el "GetErrorString" en dspickle.cpp usa el DBIMAXMSGLEN constante que se define en bdetypes.h como 127 (la mitad de 255). Como estamos en el mundo de Unicode, no se trata de aumentar este valor a 255 para tener dos bytes por carácter. Esto es solo una suposición ...
Dejo la pregunta en el aire porque no tengo el conocimiento para entender C++ :) Quien puede ayudar, solo mire la implementación de la función "GetErrorString" en dspickle.cpp. No es éste:
LoadString((HINSTANCE)hDll, iErrCode, pString, DBIMAXMSGLEN)
PString es el mensaje de error y DBIMAXMSGLEN = 127.
En casos de errores de SQL, generalmente el Proveedor de bases de datos trunca el mensaje de error y está fuera del alcance de su código Delphi (lo que significa que el problema está en el proveedor de la base de datos en lugar de Delphi o su código). – LaKraven
@LaKraven - ¿Qué quieres decir? No hay forma de obtener el mensaje de error completo? –
Si en este caso es su proveedor de base de datos truncar el mensaje de error, entonces sí ... no hay forma de obtener el mensaje completo (a menos que pueda reconfigurar el proveedor para dar mensajes completos?) – LaKraven