update bug catcher on client side

This commit is contained in:
Nicolas Demers 2024-04-18 08:50:24 -04:00
parent 29a780ac6a
commit 586f2344df
1 changed files with 74 additions and 58 deletions

View File

@ -1,69 +1,85 @@
class ErrorHandler {
class ErrorHandler
{
constructor(options) { constructor(options) {
if ( options ) { if (!options) throw new Error("Options not provided");
if ( "url" in options ) { if (!options.url) throw new Error("URL is required");
this.url = options['url']; if (!options.apikey) throw new Error("API key is required");
}
else {
// throw une erreur ici
}
if ( "apikey" in options ) {
this.apikey = options['apikey'];
}
else {
// throw une erreur ici
}
}
this.url = options.url;
this.apikey = options.apikey;
this.catchError(); this.catchError();
} }
getSourceCode(lineNumber) {
return this.getInlineSourceCode(lineNumber) || this.getFullSourceWithHighlight(lineNumber);
}
getInlineSourceCode(lineNumber) {
const scripts = document.querySelectorAll('script');
for (let script of scripts) {
if (!script.src) {
const scriptLines = script.textContent.split("\n");
const scriptPosition = this.getErrorPosition(script);
if (lineNumber >= scriptPosition.startLine && lineNumber <= scriptPosition.endLine) {
return this.highlightSource(scriptLines, lineNumber - scriptPosition.startLine);
}
}
}
return null;
}
getFullSourceWithHighlight(lineNumber) {
const lines = document.documentElement.outerHTML.split("\n");
return this.highlightSource(lines, lineNumber - 1);
}
highlightSource(lines, lineNumber) {
const start = Math.max(lineNumber - 2, 0);
const end = Math.min(lineNumber + 2, lines.length - 1);
lines[lineNumber] = '>> ' + lines[lineNumber] + ' <<';
return lines.slice(start, end + 1).join("\n");
}
getErrorPosition(script) {
let totalLines = 0;
let element = script.previousElementSibling;
while (element) {
totalLines += (element.outerHTML || element.textContent).split("\n").length;
element = element.previousElementSibling;
}
return {
startLine: totalLines + 1,
endLine: totalLines + script.textContent.split("\n").length
};
}
catchError() { catchError() {
window.onerror = (message, url, lineNumber, column, error) => {
this.reportError(message, url, lineNumber, column, error.stack, 'JavaScript Error');
return false;
};
console.log(this.url); window.addEventListener('unhandledrejection', event => {
this.reportError(event.reason.toString(), document.location.href, 0, 0, event.reason.stack, 'Promise Rejection');
});
}
window.onerror = function(message, url, line, column, error) { reportError(message, url, lineNumber, column, stack, type = 'JavaScript Error') {
// build l'url ET l'api key ensemble pour créer l'URL de réception de bug fetch(this.url ? `${location.protocol}//${this.url}/${this.apikey}` : window.location.href, {
fetch(this.url ? this.url : window.location.href, {
method: "post", method: "post",
headers: { headers: {
'Accept': "application/json", 'Accept': "application/json",
'Content-Type': "application/json", 'Content-Type': "application/json"
'User-Agent': "NegundoClient/1.0"
}, },
body: JSON.stringify({ body: JSON.stringify({
message: message, type,
url: url, message,
line: line, url,
column: column, lineNumber,
stack: error.stack, column,
location: window.location.toString() stack,
location: window.location.href,
source: this.getSourceCode(lineNumber)
}) })
}).then( response => response ).then(data => { }).then(response => response.json()).then(console.info);
console.info("Error reported", data);
});
return false;
}.bind(this);
}
get url() {
return this._url;
}
set url(set) {
return this._url = set;
}
get apikey() {
return this._apikey;
}
set apikey(set) {
return this._apikey = set;
} }
} }