2010-05-04 19 views
14

Sto utilizzando ELMAH per registrare i miei errori .net. Funziona alla grande, ma voglio estendere la registrazione degli errori per includere errori lato client, cioè errori JavaScript arbitrari. Posso catturare gli errori usando l'evento window.onerror e poi chiamare un gestore .net (.ashx) per registrare l'errore in elmah, ma questo è solo il mio piccolo trucco per risolvere il problema. C'è un modo migliore per registrare l'errore del lato client su elmah?Registrazione errori client con Elmah

+0

e mi piacerebbe anche essere in grado di registrare errori classici asp –

+0

ottenuto un bit interessante di javascript andando ora a catturare errori che possono essere semplicemente inclusi in qualsiasi pagina, ma sembra ancora un hack –

+0

ciao Daniel, potrebbe pubblichi il javascript che stai usando per questo? –

risposta

1

Cattura tutti gli errori javascript gestendo l'evento window.onerror ed effettuare chiamate Ajax per errore accedere manualmente 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; 
} 

No è stata trovata una soluzione migliore al momento.

3

Dai un'occhiata a hoptoadapp.com e come fanno i report javascript.

E 'esattamente la stessa cosa, ma un backend diverso :-)

+0

Questo sembra fantastico! Perché non ne ho mai sentito parlare prima? :-) –

+0

Buona cosa potrei aiutare! Potresti marcare la domanda come accettata? ;-) – changelog

9

Ecco una soluzione più completa (penso ho afferrato dal sito ELMAH ... non ricordo)

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"; 
    } 

Layout/pagina master:

<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

Non funziona. 'msg' è una stringa, non contiene i campi fileName, stack ...' arguments.callee.trace() 'restituirà solo la chiamata precedente (cioè il gestore onerror). – Gabriel

+1

Funziona.msg contiene tutte le informazioni meno lo stack di chiamate. Ti dice il numero di riga e l'errore. Ad esempio: JavaScriptErrorException: TypeError Uncaught: Object [oggetto Array] non ha un metodo 'nascondere': al percorso del documento 'http: // xxxx/Report/TableBreakdown startDate = 02% 2F27% 2F2013% 2009% 3A44% 3A46 & endDate = 03 % 2F27% 2F2013% 2009% 3A44% 3A46 & ripartizione = TopIssues'. a anonymous ('Uncaught TypeError: Object [object Array] non ha alcun metodo' nascondi '', 'http: // xxxx/Reports/TableBreakdown? startDate = 02% 2F27% 2F2013% 2009% 3A44% 3A46 & endDate = 03% 2F27% 2F2013 % 2009% 3A44% 3A46 & breakdown = TopIssues ',' 130 ') – rbj325

0

dare un'occhiata a questo.

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

L'unica modifica che ho dovuto fare per il codice precedente riguardava la bundling.

ho sostituito

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

E nel mio fagotto config ho aggiunto la linea ... bundles.Add (nuovo ScriptBundle ("~/stacktrace.js"). Include ("~/Scripts/stacktrace.js"));

Ciò rende il codice compatibile con il più recente raggruppamento MVC 4.

Problemi correlati