Pregunta

Estoy escribiendo una aplicación ColdFusion, y aunque es mayormente estable, que los errores de cada tan a menudo.Porque ha sustituido a la antigua aplicación ya, a veces son los usuarios que obtengan los errores en lugar de mí.

He creado una página estupenda que la gente se obtiene cuando se obtiene un error que envía la información a mí, como el error, de referencia, de error en la página, el número de línea, etc.

La única cosa que me puede llegar a parecer que el trabajo es obtener los datos del formulario presentado, si es que hay alguno.No sé en qué página se produjo un error de antemano, de manera que no puedo salida " #formulario.campo#'.

Por ejemplo, si:

form.abc = 1
form.def = 2

¿Cómo puedo obtener los nombres de las variables y el valor de "forma", sin saber ellos de antemano?

Es este documento en bucle a través de una estructura de en algún lugar a lo largo de el camino correcto?

También, estoy buscando una buena manera de almacenar los datos en una base de datos, ya que es donde el resto de la información acerca del error se almacena, y yo realmente no quiero tener que ponerlo en un correo electrónico a mí.

¿Fue útil?

Solución

El Formulario tiene un alcance FieldNames variable que le dirá cuáles son los campos que fueron presentadas.

Usted también puede hacer StructKeyList(Form) para obtener una lista de las variables actuales en el ámbito de aplicación.Esto va a incluir también FieldNames y cualquier otras variables que han sido añadidos a la Forma ámbito de aplicación.

Cualquiera de estos podría ser utilizado dentro de una <cfloop index="CurField" list="#StructKeyList(Form)#"> - pero hay maneras más fáciles...


Si usted está en CF8 usted puede convertir el alcance a una cadena agradable y con serializeJson() y deserializeJson() funciones, el cual puede ser almacenado en un campo de base de datos.

Si estás en CF6..7, a continuación, puede descargar un llamado CFC cfjson de riaforge el que imita a estas funciones.


Por último, si estás en versiones anteriores de CF, o tienen una extraña aversión a usar JSON para el almacenamiento, usted puede lanzar su propio con un simple bucle a la que insinuó más arriba - una colección de bucle le permite bucle directamente a través de una Estructura o Alcance - tenga en cuenta que algunos molestos persona escoge 'item' en lugar de 'index' como el atributo de estos.

Ya sabemos variables de Formulario son todos los objetos simples (es decir,las cadenas) he elegido para un básico key=value[newline]key=value[newline]... el formato, que es fácil a la inversa también.

Codificación:

<cfset Output = '' />
<cfloop item="CurField" collection="#Form#">
    <cfset Output = Output & CurField & '=' & Form[CurField] & Chr(10) />
</cfloop>

<cfoutput>#Output#</cfoutput>

Decodificación:

<cfset FormData = StructNew()/>
<cfloop index="CurLine" list="#Output#" delimiters="#Chr(10)#">
    <cfset FormData[ListFirst(CurLine,'=')] = ListRest(CurLine,'=') />
</cfloop>

<cfdump var="#FormData#"/>


Una última nota importante:Como con todos suministrado por el usuario variables (Forma,Url,Cookies ámbitos) usted debe asegurarse de que los manejan correctamente para evitar agujeros de seguridad - específicamente asegúrese de que está utilizando para cfqueryparam todos sus consultas de base de datos - no quiero desviar demasiado lejos, pero se sienten libres para hacer otra pregunta, si usted necesita cualquier ayuda con cfqueryparam.


Espero que esto ayude.:)

Otros consejos

Si desea iterar manualmente sobre todos los campos del formulario, la forma más sencilla es una cfloop este modo:

<cfloop collection="#form#" item="variables.name">
  #variables.name#=(#form[variables.name]#)<br/>
</cfloop>

Pero dicho esto, a los efectos de un correo electrónico de error, lo que probablemente va a encontrar que es más fácil sólo para "volcar" el alcance formulario (que es sólo una estructura especial), así:

<cfmail
  from="errors@#cgi.server_name#"
  to="you@yourdomain.com"
  subject="Error Occurred in such and such a place"
  type="html">
    <cfdump var="#form#"/>
</cfmail>

Cuando el envío de correos electrónicos de error, me gusta incluir una segunda cfdump para el alcance de CGI (de nuevo, sólo una estructura especial) ya que esto puede proporcionar alguna otra información útil acerca de la solicitud.

Si usted tiene CF 8, que también le gusten a volcar en formato de texto, como el siguiente, ya que hará que el tamaño del mensaje más pequeño (y en mi opinión, que el mensaje sea más legible)

<cfdump var="#form#" format="text">

Nota:. format se añadió el atributo de la etiqueta cfdump para CF 8, por lo que no será capaz de utilizarlo en versiones anteriores de ColdFusion

Usted ha dicho que estabas buscando una manera de almacenar estos errores en una base de datos, y eso es una buena idea. En lugar de rodar su propia solución personalizada para eso, yo sugiero que consulte BugLogHQ . Ha sido alrededor por un tiempo y funciona bien para los demás, incluido yo, y lo mejor de todo, es GRATIS y de código abierto. Es la edad y el uso generalizado significa que será menos probable que tengan errores en su propio código y probablemente tiene más, mejores prestaciones que lo que iba a escribir.

El uso de BugLogHQ, usted no tiene que preocuparse por la pantalla del error, que acaba de enviar los datos al registro de errores y que se encarga del resto.

Form es sólo un hash / estructura, lo que sólo puede iterar a través de sus teclas:

<cfoutput>
 <cfloop collection=#form# item="field">
  #htmleditformat(field)=#htmleditformat(form[field])#<br/>
 </cfloop>
</cfoutput>

Poner los datos en una base de datos? ¿Cómo se hace eso depende de lo que quieres hacer con ella después. La solución más flexible podría ser de convertir sólo el conjunto de form (y url) en un objeto WDDX, y almacenar que en un campo blob:

<cfwddx action="cfml2wddx" input=#url# output="encodedURL"/>
<cfwddx action="cfml2wddx" input=#form# output="encodedForm"/>
<cfquery datasource="yourDSN">
 INSERT INTO errorlog (datestamp, event, script_name, path_info, url, form)
 VALUES
  (<cfqueryparam value=#now()# cfsqltype="CF_SQL_TIMESTANP"/>,
   <cfqueryparam value="your error string or cfcatch data" cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#cgi.script_name# cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#cgi.path_info# cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#encodedURL# cfsqltype="CF_SQL_BLOB"/>,
   <cfqueryparam value=#encodedForm# cfsqltype="CF_SQL_BLOB"/>)
</cfquery>

De esa manera usted tendrá acceso a todos los datos en bruto para el análisis en su tiempo libre. Un montón de otras maneras de ir sobre él, por supuesto.

Si estás usando el Application.cfc en su aplicación, basta con sustituir el método onError con la de abajo. Nota: application.settings.mode puede ser uno de los siguientes valores (dev, test, prod). application.settings.webmasteremail se debe establecer en la dirección de correo electrónico que desea la información de error enviado por correo a. A estas dos variables se debe establecer en el método onApplicationStart.

¿Qué hace esta función? Si la aplicación está configurado en modo "dev" (mediante el establecimiento de application.settings.mode = "dev") se mostrará la información de error en la pantalla. Si la aplicación se establece en cualquier otro modo (como prueba o prod) se enviará por correo electrónico y almacenar la información en una base de datos.

<cffunction name="onError" returnType="void" output="true">
    <cfargument name="exception" required="true">
    <cfargument name="eventname" type="string" required="true">
    <!--- corrects bug where <cfabort> throw an error --->
    <cfif arguments.exception.rootCause eq "coldfusion.runtime.AbortException">
        <cfreturn>
    </cfif>
    <cfsavecontent variable="errordata">
        <p>#eventname#</p>
        <cfdump var="#exception#" label="Exception Information" format="text">
        <cfdump var="#url#" label="URL Information" format="text">
        <cfdump var="#form#" label="FORM Information" format="text">
        <cfdump var="#application#" label="Application Scope" format="text">
        <cfif isdefined("session")>
            <cfdump var="#session#" label="Session Scope" format="text">
        </cfif>
        <cfif isdefined("client")>
            <cfdump var="#client#" label="Client Scope" format="text">
        </cfif>
        <cfdump var="#cgi#" label="URL Information" format="text">
    </cfsavecontent>

    <!--- will email the error inforation and display the error page --->
    <cfif application.settings.mode eq "dev">
        <p>#eventname#</p>
        #errordata#
    <cfelse>
        <cfmail to="#application.settings.webmasteremail#" from="error@#cgi.http_host#" subject="Error has occured on #cgi.http_host#" type="HTML" charset="windows-1252">
        <p>#eventname#</p>
        #errordata#
        </cfmail>

        <cfquery datasource="yourDSN">
        insert into errorlog
        (
            creationdate
            ,event
            ,info
        )
        values
        (
            <cfqueryparam value="#now()#" cfsqltype="CF_SQL_TIMESTAMP"/>
            ,<cfqueryparam value="#eventname#" cfsqltype="CF_SQL_VARCHAR"/>
            ,<cfqueryparam value="#errordata#" cfsqltype="CF_SQL_LONGVARCHAR"/>
        )
        </cfquery>

        <h2>A functional error has occurred.</h2>
        <p>A notification of this error has been automatically e-mailed to the development team; no action on your part is required.</p>
        <p>Please click the "back" button on your browser to return to the web site.  We apologize for this inconvenience.</p>
    </cfif>
</cffunction>

Si está enviando un correo electrónico a ti mismo las variables de formulario, simplemente deshacerse de ellos, así:

<cfmail type="html" ...>
    <cfdump var="#form#" label="form">
    <cfdump var="#cgi#" label="cgi">
    <cfdump var="#session#" label="session">
</cfmail>

Puede volcar todo lo que te gusta en Scopes allí. Usted puede o no puede necesitar los que he proporcionado.

Usted dijo que su problema inicial era que la aplicación está reemplazando a la antigua aplicación? ¿Está desarrollando en el mismo servidor se va a implementar en? Si es así, sólo puede cambiar el nombre de la aplicación para su copia de desarrollo -. Asegurarse de que los nombres sean únicos para evitar este problema (si eso es lo que es su problema)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top