Mr.*_*and 5 html javascript ajax jquery error-reporting
用什么方式获取js报错产生的ajaxError事件的函数调用者?
我已经用 jQuery 构建了一个 js 错误 repo 应用程序,我可以处理全局发生的正常 js 错误,但是我在 ajax 错误方面遇到了问题。正常错误的时候我可以得到错误的行号!我试图用全局 ajax 处理程序之一“ajax 错误”来捕获它们,但我不确定如何获取该 ajax 调用者或调用者名称的行号。
请看底部!
const error_log_url = '/log';
const errorPost = function (data) {
$.ajax({
url: error_log_url,
type: 'post',
data: data,
success: function (res) {
console.log(res)
}, error: function (res) {
console.log(res)
}
})
}
window.addEventListener('error', function (e) {
let params = {
message: e.message || "Exception Handler",
url: e.filename || "",
lineno: e.lineno || 0,
colno: e.colno || 0
}
errorPost(params)
}, true);
// wrap function for new error stack with adding event to certain element
window.wrap = function (func) {
// make sure you only wrap the function once
if (!func._wrapped) {
func._wrapped = function () {
try {
func.apply(this, arguments);
} catch (exception) {
throw exception
}
}
}
return func._wrapped;
}
// override add & remove event listeners with above wrap function
let addEvenListener = window.EventTarget.prototype.addEventListener;
window.EventTarget.prototype.addEventListener = function (event, callback, bubble) {
addEvenListener.call(this, event, wrap(callback), bubble);
}
let removeEventLister = window.EventTarget.prototype.removeEventListener;
window.EventTarget.prototype.removeEventListener = function (event, callback, bubble) {
removeEventLister.call(this, event, callback._wrapped || callback, bubble);
}
$(document).ajaxError(function( event, jqxhr, settings, thrownError ) {
// please look at here, how can I get the caller name that produced this error!
console.log(arguments.callee.caller)
if (settings.url != error_log_url)
errorPost({
message: event.type,
filename: event.currentTarget.location.origin + settings.url
})
});
Run Code Online (Sandbox Code Playgroud)
console.log(arguments.callee.caller) 这会打印出空值。
你看,我可以从 ErrorEvent 中获得更多信息,但我无法从 ajaxError 事件中获得诸如行号之类的详细信息!
不幸的是,看起来没有网络错误的全局事件。
不过,有一种巧妙的方法可以解决这个问题 - 如果您将一个函数附加到该ajaxSend方法,该函数在发送请求时运行,您可以立即抛出错误,然后捕获它并检查堆栈以找出调用者。然后,将适当的堆栈行放入WeakMap稍后可以检查的jqXHR对象索引中。之后,如果请求失败,则在ajaxError处理程序中使用其jqXHR对象在 WeakMap 中查找堆栈。例如:
$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
console.log(stacksByXHR.get(jqxhr));
});
const stacksByXHR = new WeakMap();
$(document).ajaxSend((event, jqXHR) => {
try {
throw new Error();
} catch({ stack }) {
let callCountNonJquery = 0;
const foundCall = stack
.split('\n')
.slice(1) // Remove the top "Error" line, contains no information
.find(line => {
if (line.includes('jquery')) {
return false;
}
callCountNonJquery++;
// First call would be the thrown error above
// Second call is the $.ajax initiator
if (callCountNonJquery === 2) {
return true;
}
});
stacksByXHR.set(jqXHR, foundCall);
}
});
$.ajax('/DoesNotExist');Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>Run Code Online (Sandbox Code Playgroud)
在我的机器上,这显示了我
Run Code Online (Sandbox Code Playgroud)at https://stacksnippets.net/js:40:3
对应于以下$.ajax('/DoesNotExist');行:
如果$.ajax位于函数内部,则函数名称也将在堆栈中可见,例如:
at https://stacksnippets.net/js:40:3
Run Code Online (Sandbox Code Playgroud)
$(document).ajaxError(function(event, jqxhr, settings, thrownError) {
console.log(stacksByXHR.get(jqxhr));
});
const stacksByXHR = new WeakMap();
$(document).ajaxSend((event, jqXHR) => {
try {
throw new Error();
} catch({ stack }) {
let callCountNonJquery = 0;
const foundCall = stack
.split('\n')
.slice(1) // Remove the top "Error" line, contains no information
.find(line => {
if (line.includes('jquery')) {
return false;
}
callCountNonJquery++;
// First call would be the thrown error above
// Second call is the $.ajax initiator
if (callCountNonJquery === 2) {
return true;
}
});
stacksByXHR.set(jqXHR, foundCall);
}
});
function myFunctionWhichRunsAjax() {
$.ajax('/DoesNotExist');
}
myFunctionWhichRunsAjax();Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |