diff --git a/app/assets/javascripts/editor/ajax.js b/app/assets/javascripts/editor/ajax.js index a6caa904..bcd79ffa 100644 --- a/app/assets/javascripts/editor/ajax.js +++ b/app/assets/javascripts/editor/ajax.js @@ -12,5 +12,6 @@ CodeOceanEditorAJAX = { $.flash.danger({ text: message.length > 0 ? message : $('#flash').data('message-failure') }); + Sentry.captureException(response); } }; \ No newline at end of file diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb index b394beb0..bfcf6ac9 100644 --- a/app/assets/javascripts/editor/editor.js.erb +++ b/app/assets/javascripts/editor/editor.js.erb @@ -436,14 +436,21 @@ configureEditors: function () { if (result.error_messages) { const targetNode = card.find('.row .col-sm-9').eq(3); + let errorMessagesToShow = []; + result.error_messages.forEach(function (item) { + if (item) { + errorMessagesToShow.push(item) + } + }) + // one or more errors? - if (result.error_messages.length > 1) { + if (errorMessagesToShow.length > 1) { // delete all current elements targetNode.text(''); // create a new list and appand each element const ul = document.createElement("ul"); ul.setAttribute('class', 'error_messages_list'); - result.error_messages.forEach(function (item) { + errorMessagesToShow.forEach(function (item) { var li = document.createElement("li"); var text = document.createTextNode(item); li.appendChild(text); @@ -451,7 +458,7 @@ configureEditors: function () { }) targetNode.append(ul); } else { - targetNode.text(result.error_messages.join('')); + targetNode.text(errorMessagesToShow.join('')); } } //card.find('.row .col-sm-9').eq(4).find('a').attr('href', '#output-' + index); @@ -565,6 +572,7 @@ configureEditors: function () { icon: ['fa', 'fa-bug'], text: $('#run').data('message-failure') }); + Sentry.captureException(output); } }, @@ -606,7 +614,7 @@ configureEditors: function () { }); }, - showWebsocketError: function() { + showWebsocketError: function(error) { if (window.navigator.userAgent.indexOf('Edge') > -1 || window.navigator.userAgent.indexOf('Trident') > -1) { // Mute errors in Microsoft Edge and Internet Explorer return; @@ -614,6 +622,7 @@ configureEditors: function () { $.flash.danger({ text: $('#flash').data('message-failure') }); + Sentry.captureException(error); }, showFileDialog: function(event) { diff --git a/app/assets/javascripts/exercises.js.erb b/app/assets/javascripts/exercises.js.erb index 66c8dfb6..9b47729e 100644 --- a/app/assets/javascripts/exercises.js.erb +++ b/app/assets/javascripts/exercises.js.erb @@ -108,10 +108,11 @@ $(document).on('turbolinks:load', function() { } } - var ajaxError = function() { + var ajaxError = function(error) { $.flash.danger({ text: $('#flash').data('message-failure') }); + Sentry.captureException(error); }; var buildCheckboxes = function() { diff --git a/app/controllers/concerns/lti.rb b/app/controllers/concerns/lti.rb index 8257bc99..ace841d2 100644 --- a/app/controllers/concerns/lti.rb +++ b/app/controllers/concerns/lti.rb @@ -155,6 +155,13 @@ module Lti if provider.nil? {status: 'error'} elsif provider.outcome_service? + Raven.extra_context({ + provider: provider.inspect, + score: score, + lti_parameter: lti_parameter.inspect, + session: session.to_hash, + exercise_id: exercise_id + }) response = provider.post_replace_result!(score) {code: response.response_code, message: response.post_response.body, status: response.code_major} else diff --git a/app/controllers/execution_environments_controller.rb b/app/controllers/execution_environments_controller.rb index cf2160d8..66a212a8 100644 --- a/app/controllers/execution_environments_controller.rb +++ b/app/controllers/execution_environments_controller.rb @@ -121,6 +121,7 @@ class ExecutionEnvironmentsController < ApplicationController rescue DockerClient::Error => error @docker_images = [] flash[:warning] = error.message + Raven.capture_exception(error) end private :set_docker_images diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index cdc9687e..60fcf6c2 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -190,9 +190,11 @@ class SubmissionsController < ApplicationController socket.send data Rails.logger.debug('Sent the received client data to docker:' + data) end - rescue JSON::ParserError + rescue JSON::ParserError => error socket.send data Rails.logger.debug('Rescued parsing error, sent the received client data to docker:' + data) + Raven.extra_context(data: data) + Raven.capture_exception(error) end end @@ -395,7 +397,8 @@ class SubmissionsController < ApplicationController Rails.logger.debug('stopping submission ' + @submission.id.to_s) container = Docker::Container.get(params[:container_id]) DockerClient.destroy_container(container) - rescue Docker::Error::NotFoundError + rescue Docker::Error::NotFoundError => error + Raven.capture_exception(error) ensure head :ok end @@ -425,6 +428,7 @@ class SubmissionsController < ApplicationController yield(server_sent_event) if block_given? server_sent_event.write({code: 200}, event: 'close') rescue => exception + Raven.capture_exception(exception) logger.error(exception.message) logger.error(exception.backtrace.join("\n")) server_sent_event.write({code: 500}, event: 'close') diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 5b69c104..139d205b 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -8,14 +8,16 @@ // layout file, like app/views/layouts/application.html.slim // JS -import 'jquery' +import 'jquery'; import 'bootstrap/dist/js/bootstrap.bundle.min'; import 'chosen-js/chosen.jquery'; import 'jstree'; import 'underscore'; -import 'd3' +import 'd3'; +import '@sentry/browser'; window._ = _; // Publish underscore's `_` in global namespace window.d3 = d3; // Publish d3 in global namespace +window.Sentry = Sentry; // Publish sentry in global namespace // CSS import 'chosen-js/chosen.css'; diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index 2c8cb36c..2ba1967f 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -17,6 +17,21 @@ html lang='en' script type="text/javascript" | I18n.defaultLocale = "#{I18n.default_locale}"; | I18n.locale = "#{I18n.locale}"; + | Sentry.init({ + | dsn: 'https://637ca99538224b4bb28cd9e670e1b372@sentry.xikolo.de/33', + | attachStacktrace: true, + | release: "#{Raven.configuration.release}", + | environment: "#{Raven.configuration.current_environment}", + | }); + - if @current_user + | Sentry.configureScope(function(scope) { + | scope.setUser({ + | "id": "#{@current_user.id}", + | "type": "#{@current_user.class.name}", + | "username": "#{@current_user.displayname}", + | "consumer": "#{@current_user.consumer.name}" + | }); + | }); body - unless @embed_options[:hide_navbar] nav.navbar.navbar-dark.bg-dark.navbar-expand-md.mb-4.py-1 role='navigation' diff --git a/config/webpack/environment.js b/config/webpack/environment.js index 706c8a1e..ea93de4b 100644 --- a/config/webpack/environment.js +++ b/config/webpack/environment.js @@ -19,6 +19,7 @@ environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ vis: 'vis', hljs: 'highlight.js', d3: 'd3', + Sentry: '@sentry/browser' }) ); diff --git a/package.json b/package.json index e0e73545..83d449c3 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "dependencies": { "@fortawesome/fontawesome-free": "^5.12.1", "@rails/webpacker": "4.2", + "@sentry/browser": "^5.13.2", "bootstrap": "^4.1.3", "bootswatch": "^4.4.1", "chosen-js": "^1.8.7", diff --git a/yarn.lock b/yarn.lock index fc259d4d..cf715e6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -801,6 +801,58 @@ webpack-cli "^3.3.10" webpack-sources "^1.4.3" +"@sentry/browser@^5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.13.2.tgz#fcca630c8c80447ba8392803d4e4450fd2231b92" + integrity sha512-4MeauHs8Rf1c2FF6n84wrvA4LexEL1K/Tg3r+1vigItiqyyyYBx1sPjHGZeKeilgBi+6IEV5O8sy30QIrA/NsQ== + dependencies: + "@sentry/core" "5.13.2" + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/core@5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.13.2.tgz#d89e199beef612d0a01e5c4df4e0bb7efcb72c74" + integrity sha512-iB7CQSt9e0EJhSmcNOCjzJ/u7E7qYJ3mI3h44GO83n7VOmxBXKSvtUl9FpKFypbWrsdrDz8HihLgAZZoMLWpPA== + dependencies: + "@sentry/hub" "5.13.2" + "@sentry/minimal" "5.13.2" + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/hub@5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.13.2.tgz#875a5ba983d6ada5caae5b6b4decd0257ef5cdb7" + integrity sha512-/U7yq3DTuRz8SRpZVKAaenW9sD2F5wbj12kDVPxPnGspyqhy0wBWKs9j0YJfBiDXMKOwp3HX964O3ygtwjnfAw== + dependencies: + "@sentry/types" "5.13.2" + "@sentry/utils" "5.13.2" + tslib "^1.9.3" + +"@sentry/minimal@5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.13.2.tgz#e42e33dc74fc935f8857d1a43a528afd741640fd" + integrity sha512-VV0eA3HgrnN3mac1XVPpSCLukYsU+QxegbmpnZ8UL8eIQSZ/ZikYxagDNlZbdnmXHUpOEUeag2gxVntSCo5UcA== + dependencies: + "@sentry/hub" "5.13.2" + "@sentry/types" "5.13.2" + tslib "^1.9.3" + +"@sentry/types@5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.13.2.tgz#8e68c31f8fb99b4074374bff13ed01035b373d8c" + integrity sha512-mgAEQyc77PYBnAjnslSXUz6aKgDlunlg2c2qSK/ivKlEkTgTWWW/dE76++qVdrqM8SupnqQoiXyPDL0wUNdB3g== + +"@sentry/utils@5.13.2": + version "5.13.2" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.13.2.tgz#441594f4f9412bfd1690739ce986bf3a49687806" + integrity sha512-LwPQl6WRMKEnd16kg35HS3yE+VhBc8vN4+BBIlrgs7X0aoT+AbEd/sQLMisDgxNboCF44Ho3RCKtztiPb9blqg== + dependencies: + "@sentry/types" "5.13.2" + tslib "^1.9.3" + "@snyk/cli-interface@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-1.5.0.tgz#b9dbe6ebfb86e67ffabf29d4e0d28a52670ac456" @@ -5468,7 +5520,16 @@ nconf@^0.10.0: secure-keys "^1.0.0" yargs "^3.19.0" -needle@^2.2.4, needle@^2.4.0: +needle@^2.2.4: + version "2.3.3" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.3.tgz#a041ad1d04a871b0ebb666f40baaf1fb47867117" + integrity sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +needle@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== @@ -7870,10 +7931,10 @@ snyk-try-require@1.3.1, snyk-try-require@^1.1.1, snyk-try-require@^1.3.1: lru-cache "^4.0.0" then-fs "^2.0.0" -snyk@^1.298.0: - version "1.298.0" - resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.298.0.tgz#2edd49e59fb2d79181a2ce41272ff4bf77521cae" - integrity sha512-5MH//I69+g7cXnBDRy4vH2QWEKlOHZF8rsAoyT/NCnd//kczsi2hiP3vwbyTUTYngxeutLiDpLv76un/Spf1rA== +snyk@^1.297.3: + version "1.297.4" + resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.297.4.tgz#7a8886eaa19c3215e9bb617739b873865f0da31d" + integrity sha512-NPmBfVgyVsMI+wfulUh8eDoNRK2Gr+bVnqTWJ6aNhFED1NUfmFfNjYuDNs/6VxeljpHinVE3VskxzRkSAlE+pA== dependencies: "@snyk/cli-interface" "2.3.2" "@snyk/configstore" "^3.2.0-rc1"