diff --git a/.gitignore b/.gitignore index 91fa5cc..4935f7a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ node_modules/ package.json package-lock.json .tox/ +build/ diff --git a/README.rst b/README.rst index a88c311..aa38979 100644 --- a/README.rst +++ b/README.rst @@ -93,9 +93,9 @@ Then install the urls:: In your template, simply add the js_error_hook script:: - + Now every JavaScript error will be logged in your logging error stream. (Mail, Sentry, ...) diff --git a/demo/demoproject/templates/error_test.html b/demo/demoproject/templates/error_test.html index da16462..08f9490 100644 --- a/demo/demoproject/templates/error_test.html +++ b/demo/demoproject/templates/error_test.html @@ -1,3 +1,4 @@ +{% load static %} @@ -6,7 +7,10 @@ - + + diff --git a/demo/setup.py b/demo/setup.py index 06d3afc..f8538be 100644 --- a/demo/setup.py +++ b/demo/setup.py @@ -25,8 +25,7 @@ def read_relative_file(filename): classifiers=[ "Development Status :: 1 - Planning", "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 3", "Framework :: Django", ], keywords="class-based view, generic view, js error hooking", diff --git a/django_js_error_hook/static/django_js_error_hook/utils.js b/django_js_error_hook/static/django_js_error_hook/utils.js deleted file mode 100644 index 1c55f9d..0000000 --- a/django_js_error_hook/static/django_js_error_hook/utils.js +++ /dev/null @@ -1,60 +0,0 @@ -(function () { - function getCookie (name) { - const nameEQ = name + '=' - const ca = document.cookie.split(';') - for (let i = 0; i < ca.length; i++) { - let c = ca[i] - while (c.charAt(0) === ' ') c = c.substring(1, c.length) - if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length) - } - return null - } - - function logError (details) { - const xhr = new XMLHttpRequest() - - xhr.open('POST', window.djangoJSErrorHandlerUrl, true) - xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded') - const cookie = getCookie('csrftoken') - if (cookie) { - xhr.setRequestHeader('X-CSRFToken', cookie) - } - const query = [] - const data = { - context: navigator.userAgent, - details - } - for (const key in data) { - query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])) - } - xhr.send(query.join('&')) - } - - window.onerror = function (msg, url, lineNumber, columnNumber, errorObj) { - let logMessage = url + ': ' + lineNumber + ': ' + msg - if (columnNumber) { - logMessage += ', ' + columnNumber - } - if (errorObj && errorObj.stack) { - logMessage += ', ' + errorObj.stack - } - logError(logMessage) - } - - if (window.addEventListener) { - window.addEventListener('unhandledrejection', function (rejection) { - let logMessage = rejection.type - if (rejection.reason) { - if (rejection.reason.message) { - logMessage += ', ' + rejection.reason.message - } else { - logMessage += ', ' + JSON.stringify(rejection.reason) - } - if (rejection.reason.stack) { - logMessage += ', ' + rejection.reason.stack - } - } - logError(logMessage) - }) - } -})() diff --git a/django_js_error_hook/static/js/django_js_error_hook.js b/django_js_error_hook/static/js/django_js_error_hook.js new file mode 100644 index 0000000..e767703 --- /dev/null +++ b/django_js_error_hook/static/js/django_js_error_hook.js @@ -0,0 +1,82 @@ +(function () { + function getCookie (name) { + if (!document.cookie || document.cookie === '') { + return null + } + const cookie = document.cookie.split(';').map(cookie => cookie.trim()).find(cookie => { + if (cookie.substring(0, name.length + 1) === (name + '=')) { + return true + } else { + return false + } + }) + if (cookie) { + return decodeURIComponent(cookie.substring(name.length + 1)) + } + return null + } + function logError (details) { + const cookie = getCookie('csrftoken') + const data = { + context: String(navigator.userAgent), + details: String(details) + } + + if (window.fetch) { + const body = new FormData() + body.append('context', data.context) + body.append('details', data.details) + + return fetch(window.djangoJSErrorHandlerUrl, { + method: 'POST', + headers: { + 'X-CSRFToken': cookie + }, + credentials: 'include', + body + }) + } else { + const xhr = new XMLHttpRequest() + + xhr.open('POST', window.djangoJSErrorHandlerUrl, true) + xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded') + + if (cookie) { + xhr.setRequestHeader('X-CSRFToken', cookie) + } + const query = [] + for (const key in data) { + query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])) + } + xhr.send(query.join('&')) + } + } + + window.onerror = function (msg, url, lineNumber, columnNumber, errorObj) { + let logMessage = url + ': ' + lineNumber + ': ' + msg + if (columnNumber) { + logMessage += ', ' + columnNumber + } + if (errorObj && errorObj.stack) { + logMessage += ', ' + errorObj.stack + } + logError(logMessage) + } + + if (window.addEventListener) { + window.addEventListener('unhandledrejection', function (rejection) { + let logMessage = rejection.type + if (rejection.reason) { + if (rejection.reason.message) { + logMessage += ', ' + rejection.reason.message + } else { + logMessage += ', ' + JSON.stringify(rejection.reason) + } + if (rejection.reason.stack) { + logMessage += ', ' + rejection.reason.stack + } + } + logError(logMessage) + }) + } +})()