FGLLDPATH y FGLRESOURCEPATH en Genero: errores -6206 y -1110

El problema: errores -6206 y -1110 al copiar el programa

Cuando un programa Genero funciona en su carpeta de instalación y falla al copiarlo a otra, casi siempre es cuestión de FGLLDPATH (módulos) y FGLRESOURCEPATH (formularios). El caso típico: un programa funciona en su carpeta de instalación. Copias una versión nueva a una carpeta de pruebas para probarla antes de sustituir la buena, la lanzas, y falla con uno de estos dos errores:

Program stopped at 'app.4gl', line number 5.
FORMS statement error number -6206.
The 42m module 'comun' could not be loaded, check FGLLDPATH environment variable.
Program stopped at 'comun.4gl', line number 3.
FORMS statement error number -1110.
Form file (ayuda) not found.

El programa no ha cambiado en nada que tenga que ver con comun ni con ayuda. Lo que falta en la carpeta de pruebas son las piezas compartidas, el módulo común y su formulario, que en la instalación sí estaban al lado del programa.

La causa: dos variables y dos órdenes distintos

El runtime busca los módulos (.42m) y los recursos (.42f, .4st, .4ad, .42s…) con variables distintas y en un orden distinto. Según el manual:

OrdenMódulos .42m (FGLLDPATH)Recursos .42f… (FGLRESOURCEPATH)
1Directorio actualDirectorio actual
2Directorio del programaFGLRESOURCEPATH (o DBPATH)
3FGLLDPATH$FGLDIR/lib
4$FGLDIR/libDirectorio del programa

«Directorio del programa» es donde está el .42m que contiene el MAIN (o el .42r, si el programa está enlazado).

Lo que hay que tener presente:

  • Para los módulos, la carpeta del programa es el segundo sitio donde se busca. Para los formularios, es el último.
  • Si lanzas el programa instalado con su ruta absoluta desde cualquier carpeta, todo se resuelve por la carpeta del programa y funciona.
  • La copia de pruebas tiene como carpeta del programa la de pruebas, donde no están las piezas comunes. Ningún paso de la búsqueda llega a la instalación.

Reproducirlo

Dos carpetas. prod/ tiene el programa, un módulo común y su formulario. pruebas/ tiene solo una copia de app.42m:

-- comun.gl
PUBLIC FUNCTION abrir_ayuda()
  OPEN FORM f_ayuda FROM "ayuda"
  DISPLAY "formulario ayuda cargado"
  CLOSE FORM f_ayuda
END FUNCTION
-- app.4gl
IMPORT FGL comun
MAIN
  DISPLAY "arranca app"
  CALL comun.abrir_ayuda()
  DISPLAY "fin app"
END MAIN
-- ayuda.per
LAYOUT
GRID
{
Ayuda
}
END
END

El ejemplo solo carga el formulario con OPEN FORM, sin mostrarlo, así que LAYOUT vale también en modo texto. Para mostrarlo en una ventana en modo texto haría falta una sección SCREEN.

cd prod
fglcomp -W all comun.4gl && fglcomp -W all app.4gl && fglform ayuda.per
cp app.42m ../pruebas/

Con FGLLDPATH y FGLRESOURCEPATH vacías:

Cómo se lanzaResultado
cd prod; fglrun app.42mFunciona
cd /tmp; fglrun /ruta/prod/app.42mFunciona: todo se encuentra en la carpeta del programa
cd pruebas; fglrun app.42m-6206: no encuentra comun.42m
Igual, con FGLLDPATH=/ruta/prod-1110: ya encuentra el módulo, pero no el formulario
Igual, con FGLLDPATH y FGLRESOURCEPATH a /ruta/prodFunciona

Corregir solo FGLLDPATH cambia un error por otro. Hacen falta las dos variables.

Un detalle de la salida: «arranca app» se imprime antes del -6206. El módulo importado no se carga al arrancar, sino la primera vez que se usa (línea 5), así que el error puede salir lejos de donde empieza el programa.

La solución

Añadir la carpeta de instalación al final de las dos variables, por ejemplo en el perfil de la shell de quien prueba:

export FGLLDPATH=$FGLLDPATH:/opt/miapp/bin
export FGLRESOURCEPATH=$FGLRESOURCEPATH:/opt/miapp/bin

La carpeta de pruebas solo necesita los ficheros propios del programa que se está probando. Lo común se sigue cogiendo de la instalación.

El orden importa, y no es el mismo para los dos tipos de fichero:

  • Módulos: el directorio actual y el del programa se buscan antes que FGLLDPATH. Si en pruebas hay un comun.42m nuevo junto al programa, se usa ese y no el de la instalación.
  • Formularios: el directorio del programa es el último, después de FGLRESOURCEPATH. Si en pruebas hay un ayuda.42f nuevo junto al programa y la instalación está en FGLRESOURCEPATH, gana el de la instalación. El nuevo solo gana si está en el directorio actual, es decir, si lanzas el programa desde la carpeta de pruebas (cd pruebas; fglrun app.42m) y no con su ruta desde otra carpeta.

Comprobado con versiones distintas del mismo fichero en cada sitio, lanzando el programa desde una carpeta vacía:

Mismo fichero en…Gana
Carpeta del programa y FGLLDPATH (.42m)La carpeta del programa
Carpeta del programa y FGLRESOURCEPATH (.42f)FGLRESOURCEPATH
Directorio actual y FGLRESOURCEPATH (.42f)El directorio actual

Si el programa se lanza siempre con un script, las mismas dos líneas pueden ir en el script, antes de lanzar fglrun. Así no dependes del perfil de cada usuario.

La otra cara: lo viejo del directorio actual

El directorio actual va primero en las dos búsquedas. Si lanzas el programa instalado desde una carpeta donde quedó un comun.42m antiguo, el programa usa el antiguo sin avisar:

$ cd carpeta_con_restos
$ fglrun /ruta/prod/app.42m
*** comun VIEJO del directorio actual ***
fin app

Es la misma regla que en el caso anterior, pero en contra. Antes de buscar un fallo raro en el código, mira desde dónde se lanza el programa.

Diagnóstico rápido

ErrorQué faltaVariable
-6206 The 42m module ‘X’ could not be loadedX.42mFGLLDPATH
-1110 Form file (X) not foundX.42fFGLRESOURCEPATH

Una diferencia práctica entre los dos:

  • -6206 está en la lista de errores no capturables. Ni WHENEVER ni TRY/CATCH lo interceptan: el programa se para siempre.
  • -1110 sí se puede capturar. Pero un TRY/CATCH en el llamante no lo ve si el error salta dentro de la función llamada, aunque sea del mismo módulo, salvo que esa función esté bajo un WHENEVER ERROR RAISE. Lo cuenta la entrada de TRY/CATCH.

Conclusión

Si un programa funciona instalado y falla copiado en otra carpeta, casi nunca es el programa. Son dos búsquedas distintas, y la carpeta del programa ocupa un sitio distinto en cada una: segunda para los módulos y última para los recursos. Añadir la instalación al final de FGLLDPATH y de FGLRESOURCEPATH resuelve los dos errores sin copiar nada.

Fuentes

  • Manual Genero BDL 6.00: variables de entorno FGLLDPATH y FGLRESOURCEPATH; tabla de errores (-6206, -1110); Non-trappable errors; Exception actions (WHENEVER ERROR RAISE).

Qué está comprobado y qué no

Los órdenes de búsqueda, los mensajes de error, que -6206 no es capturable y el ejemplo de -1110 con WHENEVER ERROR RAISE están contrastados con el manual de Genero 6.00.

Reproducido en Genero 5.01.04 con el programa de ejemplo, en modo texto (FGLGUI=0). Los listados de app.4gl, comun.4gl y ayuda.per se copiaron tal cual del texto de la entrada, así que los números de línea de los errores son los de esos listados:

  • Las cinco formas de lanzarlo de la primera tabla.
  • Los tres conflictos de la segunda tabla. Para saber qué .42f se había cargado, cada versión del formulario tenía un campo con distinto nombre y el programa comprobaba cuál existía. Como esa prueba muestra el formulario en una ventana (OPEN WINDOW ... WITH FORM), en modo texto tuvo que usar SCREEN en vez de LAYOUT; con LAYOUT sale el error -6315 («The form is too complex for the console-ui»).
  • El módulo viejo del directorio actual que tapa al instalado.

También se comprobó que el -6206 atraviesa un TRY/CATCH, y que el -1110 lanzado desde una función llamada (de otro módulo y del mismo) solo se captura con WHENEVER ERROR RAISE.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *


Scroll al inicio