2010-05-04 15 views
14

Estoy usando ELMAH para registrar mis errores .net. Está funcionando muy bien, pero quiero extender el registro de errores para incluir errores del lado del cliente, es decir, errores arbitrarios de JavaScript. Puedo capturar los errores usando el evento window.onerror y luego llamar a un controlador .net (.ashx) para registrar el error en elmah, pero este es solo mi pequeño truco para resolver el problema. ¿Hay alguna forma mejor de registrar el error del lado del cliente en elmah?Clientside error logging using Elmah

+0

y también me gustaría poder registrar errores clásicos de asp –

+0

tengo un poco de javascript interesante ahora para capturar errores que simplemente pueden incluirse en cualquier página, pero todavía se siente como un truco –

+0

hola Daniel, podría ¿publicas el javascript que estás utilizando para esto? –

Respuesta

1

captura todos los errores de javascript por controlar el evento y hacer window.onerror llamada AJAX para registrar manualmente error en ELMAH

window.onerror = function (msg, url, linenumber) { 

//make ajax call with all error details and log error directly into the elmah database 

//show freindly error msg here to user 

//hide error from browser 
return true; 
} 

n mejor solución se encontró en el momento.

3

Eche un vistazo a hoptoadapp.com y cómo hacen los informes de javascript.

Es exactamente lo mismo, pero un motor diferente :-)

+0

¡Esto se ve muy bien! ¿Por qué no he escuchado antes sobre esto? :-) –

+0

¡Qué bueno que podría ayudar! ¿Podría marcar la pregunta como aceptada? ;-) – changelog

9

Aquí es una solución más completa (creo que lo agarré del sitio ELMAH ... no recuerdo)

ErrorLogging.js:

window.onerror = function (msg, url, line) { 
     logError(msg, arguments.callee.trace()); 
    } 
    function logError(ex, stack) { 
     if (ex == null) return; 
     if (logErrorUrl == null) { 
      alert('logErrorUrl must be defined.'); 
      return; 
     } 

     var url = ex.fileName != null ? ex.fileName : document.location; 
     if (stack == null && ex.stack != null) stack = ex.stack; 

     // format output 
     var out = ex.message != null ? ex.name + ": " + ex.message : ex; 
     out += ": at document path '" + url + "'."; 
     if (stack != null) out += "\n at " + stack.join("\n at "); 

     // send error message 
     jQuery.ajax({ 
      type: 'POST', 
      url: logErrorUrl, 
      data: { message: out } 
     }); 
    } 

    Function.prototype.trace = function() 
    { 
     var trace = []; 
     var current = this; 
     while(current) 
     { 
      trace.push(current.signature()); 
      current = current.caller; 
     } 
     return trace; 
    } 

    Function.prototype.signature = function() 
    { 
     var signature = { 
      name: this.getName(), 
      params: [], 
      toString: function() 
      { 
       var params = this.params.length > 0 ? 
        "'" + this.params.join("', '") + "'" : ""; 
       return this.name + "(" + params + ")" 
      } 
     }; 
     if (this.arguments) 
     { 
      for(var x=0; x<this.arguments.length; x++) 
       signature.params.push(this.arguments[x]); 
     } 
     return signature; 
    } 

    Function.prototype.getName = function() 
    { 
     if (this.name) 
      return this.name; 
     var definition = this.toString().split("\n")[0]; 
     var exp = /^function ([^\s(]+).+/; 
     if (exp.test(definition)) 
      return definition.split("\n")[0].replace(exp, "$1") || "anonymous"; 
     return "anonymous"; 
    } 

Formato/página maestra:

<script src="@Url.Content("~/Scripts/ErrorLogging.js")" type="text/javascript"></script> 

<script type="text/javascript"> 
    //This needs to be here to be on everypage 
    var logErrorUrl = '@Url.Action("LogJavaScriptError", "Home")'; 
</script> 

HomeController.cs:

[HttpPost] 
    public void LogJavaScriptError(string message) { 
     ErrorSignal.FromCurrentContext().Raise(new JavaScriptErrorException(message)); 
    } 

JavaScriptErrorException.cs:

[Serializable] 
public class JavaScriptErrorException: Exception{ 
    public JavaScriptErrorException(string message) : base (message){} 
} 
+1

No funciona. 'msg' es una cadena, no contiene los campos nombreArchivo, pila ...' arguments.callee.trace() 'devolverá solo la llamada anterior (es decir, el controlador onerror). – Gabriel

+1

Funciona.msg contiene toda la información menos la pila de llamadas. Le dice el número de línea y el error. Por ejemplo: JavaScriptErrorException: UnEught TypeError: Object [object Array] no tiene el método 'hide': en la ruta del documento 'http: // xxxx/Reports/TableBreakdown? StartDate = 02% 2F27% 2F2013% 2009% 3A44% 3A46 & endDate = 03 % 2F27% 2F2013% 2009% 3A44% 3A46 y desglose = TopIssues '. at anonymous ('Unkeught TypeError: Object [object Array] no tiene el método' hide '', 'http: // xxxx/Reports/TableBreakdown? startDate = 02% 2F27% 2F2013% 2009% 3A44% 3A46 & endDate = 03% 2F27% 2F2013 % 2009% 3A44% 3A46 y desglose = TopIssues ',' 130 ') – rbj325

0

miren esto.

http://joel.net/logging-errors-with-elmah-in-asp.net-mvc-3--part-5--javascript

La única modificación que tenía que hacer para que el código anterior se refería a la agrupación.

que sustituyen

... con @ Scripts.Render ("~/stacktrace.js")

Y en mi config paquete añadí la línea ... bundles.Add (nuevo ScriptBundle ("~/stacktrace.js"). Include ("~/Scripts/stacktrace.js"));

Esto hace que el código sea compatible con la nueva agrupación MVC 4.