Регистрация ошибок Clientside с использованием Elmah
Я использую ELMAH для регистрации моих ошибок .net. Он отлично работает, но я хочу расширить регистрацию ошибок, чтобы включить ошибки на стороне клиента, то есть произвольные ошибки JavaScript. Я могу зафиксировать ошибки с помощью события window.onerror, а затем вызвать обработчик .net(.ashx) для регистрации ошибки в elmah, но это всего лишь мой маленький взлом, чтобы решить проблему. Есть ли лучший способ зарегистрировать ошибку на стороне клиента в elmah?
Ответы
Ответ 1
Поймайте все ошибки javascript, обработав событие window.onerror и сделайте ajax-вызов вручную зарегистрировать ошибку в 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;
}
В то время не было найдено лучшего решения.
Ответ 2
Здесь более полное решение (я думаю, что я схватил его с сайта ELMAH... не могу вспомнить)
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";
}
Макет/Мастер-страница:
<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 ){}
}
Ответ 3
Взгляните на hoptoadapp.com и как они сообщают javascript.
Это то же самое, но другое бэкэнд: -)
Ответ 4
Взгляните на это.
http://joel.net/logging-errors-with-elmah-in-asp.net-mvc-3--part-5--javascript
Единственная модификация, которую я должен был внести в вышеуказанный код, касался связывания.
Я заменил
... с
@Scripts.Render( "~/stacktrace.js" )
И в моей конфигурации пакета я добавил строку...
bundles.Add(новый ScriptBundle ( "~/stacktrace.js" ). Включить ( "~/Scripts/stacktrace.js" ));
Это делает код совместимым с новой связью MVC 4.