Skip to content

Commit

Permalink
Merge branch 'client_javascript_error_logging'
Browse files Browse the repository at this point in the history
Former-commit-id: ed2f579e4dcaf7f97ce66f60dd0ee4c0ecc3eb44 [formerly 7c82537bafed8544cd482ced535df0d6df79f23a] [formerly 45cc26a837babb74582666cdbdf5ae0bd278897c [formerly c806727d4393ea59401da2413f42eb9131203387]] [formerly 82387bfcc3f5c12717f2777694d77a7095f99c08 [formerly 77d0ef590a0182a79072383b5367147992c61b3f] [formerly b63b0b45b5174ac25362fcb54668bcb5a4798ebd [formerly b63b0b45b5174ac25362fcb54668bcb5a4798ebd [formerly 092fa087182201ef13a9b03c3da3933f2f506808]]]]
Former-commit-id: 54de29383976257b1260841958aded1216b4a3b6 [formerly 01ea2af5bd0d6a7474f43afa80d8a1ff224da4c2] [formerly f9a0346a1942e4490e31a7ed989d5f2df80a2ece [formerly 3101f0c7581a2dbbfdcc3dac2389f7f55fedb1d6]]
Former-commit-id: 3c187f27f92025d0a4bc7377a41c1bd11f5b9a38 [formerly 23d73e80518f7ee6a49c8c9c4123afd49375c5ac]
Former-commit-id: e6572a7f8f5f19260b9acecbf850624c05779256
Former-commit-id: 9bfb50f
  • Loading branch information
tkriplean committed Jan 23, 2014
2 parents e1905fe + 2d047e5 commit befe858
Show file tree
Hide file tree
Showing 19 changed files with 358 additions and 30 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ gem 'sitemap_generator'
#gem 'cacheable-csrf-token-rails'
gem 'cacheable-csrf-token-rails', :git => 'git://github.com/ekampp/cacheable-csrf-token-rails'

# https://github.com/josh/useragent
gem 'useragent'

#######
# https://github.com/rails/protected_attributes
# These are primarily to make smooth upgrade from Rails 3 to 4
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ GEM
uglifier (2.4.0)
execjs (>= 0.3.0)
json (>= 1.8.0)
useragent (0.10.0)
uuidtools (2.1.4)
warden (1.2.3)
rack (>= 1.0)
Expand Down Expand Up @@ -495,5 +496,6 @@ DEPENDENCIES
trackable!
twitter
uglifier
useragent
whenever
yamler
24 changes: 24 additions & 0 deletions app/assets/javascripts/backbone/app.js.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@

App.commands.setHandler "unregister:instance", (instance, id) ->
App.unregister instance, id if App.environment is "development"

window.onerror = (msg, url, line, column, error_obj) ->


trace = if error_obj? then error_obj.stack else null # works in chrome for now

attrs = ['javascript', msg, url, line].join()
if window.xx_last_js_error != attrs
App.vent.trigger 'javascript:error', 'js', trace, msg, window.location.pathname, line
window.xx_last_js_error = attrs

suppress_errors = true
# If you return true, then error alerts (like in older versions of Internet Explorer) will be suppressed.
return suppress_errors

$( document ).ajaxError (event, jqxhr, settings, exception) ->
attrs = ['ajax', exception, settings.url, settings.type].join()

console.log exception
if window.xx_last_ajax_error != attrs
App.vent.trigger 'javascript:error', 'ajax', settings.data, exception, settings.url, settings.type
window.xx_last_ajax_error = attrs


App.addInitializer ->
$.get Routes.get_avatars_path(), (data) ->
Expand Down Expand Up @@ -67,4 +90,5 @@

App.vent.trigger 'App:Initialization:Complete'


App
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
'change #password_has' : 'passwordHasChanged'
'change #password_none' : 'passwordNoneChanged'
'validated #user_email,#user_password' : 'checkIfSubmitEnabled'
'click .m-user-accounts-register-next' : 'registerAccount'
'click [data-target="create-account"]' : 'registerAccount'

setInput : (has_password) ->
if has_password
Expand All @@ -102,8 +102,8 @@

toggleInput : (has_password) ->
$password_area = @$el.find('#password_has').siblings('.m-user-account-password')
$submit_button_login = @$el.find('.m-user-accounts-login-submit')
$submit_button_register = @$el.find('.m-user-accounts-register-next')
$submit_button_login = @$el.find('[data-target="login-submit"]')
$submit_button_register = @$el.find('[data-target="create-account"]')
if !has_password
$password_area.css
opacity : '.5'
Expand Down Expand Up @@ -131,8 +131,8 @@
checkIfSubmitEnabled : ->
$email_field = @$el.find('#user_email')
$password_field = @$el.find('#user_password')
$submit_button_login = @$el.find('.m-user-accounts-login-submit')
$submit_button_register = @$el.find('.m-user-accounts-register-next')
$submit_button_login = @$el.find('[data-target="login-submit"]')
$submit_button_register = @$el.find('[data-target="create-account"]')
is_new_user = @$el.find('#password_none:checked').length > 0 && !@options.fixed

if is_new_user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,23 @@

getLayout : ->
new Admin.DatabaseView

class Admin.ClientErrorsController extends Admin.AdminController
auth : 'is_developer'
admin_template_needed : true

data_uri : ->
Routes.client_error_path()

process_data_from_server : (data) ->
App.vent.trigger 'javascript:errors:fetched', data.errors
data

setupLayout : ->
layout = @getLayout()


layout

getLayout : ->
new Admin.ClientErrorsView
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@
@trigger 'data:imported', result


class Admin.ClientErrorsView extends App.Dash.View
dash_name : 'client_errors'

serializeData : ->
_.extend {},
errors : App.request 'javascript:errors:get'



16 changes: 16 additions & 0 deletions app/assets/javascripts/backbone/apps/dash/dash_app.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dashboard/data" : "database"
"dashboard/moderate" : "moderate"
"dashboard/import_data" : "importData"
"dashboard/client_errors" : "clientErrors"

API =

Expand Down Expand Up @@ -178,6 +179,21 @@
["moderate", Routes.dashboard_moderate_path()] ]
App.request 'meta:change:default'

clientErrors : ->
$(document).scrollTop(0)

@current_controller.close() if @current_controller
@current_controller = new Dash.Admin.ClientErrorsController
region : @_getMainRegion()

if !@current_controller.redirected

App.vent.trigger 'route:completed', [
['homepage', '/'],
["client_errors", Routes.client_error_path()] ]
App.request 'meta:change:default'


unauthorizedPage : ->
@current_controller.close() if @current_controller
@current_controller = new Dash.UnauthorizedController
Expand Down
47 changes: 47 additions & 0 deletions app/assets/javascripts/backbone/entities/error.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@ConsiderIt.module "Entities", (Entities, App, Backbone, Marionette, $, _) ->

class Entities.Error extends App.Entities.Model
name: 'error'

url : () ->
Routes.report_client_error_path( )

parse : (attrs) ->
if 'client_error' of attrs
attrs.client_error
else
attrs

class Entities.Errors extends App.Entities.Collection
model: Entities.Error

parse : (attrs) ->
errors = (attr.client_error for attr in attrs)
errors

API =
all_errors : new Entities.Errors()

createError : (type, trace, msg, url, line, options = {wait : true}) ->
attrs =
error_type : type
trace : trace
line : line
location : url #window.location.href
message : msg

@all_errors.create attrs, options

addErrors : (errors) ->
@all_errors.add @all_errors.parse(errors), {merge: true}

getErrors : -> @all_errors

App.vent.on 'javascript:error', (type, trace, msg, url, line) ->
API.createError type, trace, msg, url, line

App.reqres.setHandler 'javascript:errors:get', ->
API.getErrors()

App.vent.on 'javascript:errors:fetched', (errors) ->
API.addErrors errors
2 changes: 2 additions & 0 deletions app/assets/javascripts/backbone/entities/user.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@
isAnalyst : -> @isAdmin() || @hasRole('analyst')
isEvaluator : -> @isAdmin() || @hasRole('evaluator')
isManager : -> @isAdmin() || @hasRole('manager')
isDeveloper : -> @hasRole('superadmin') || @hasRole('developer')

permissions : ->
is_admin: @isAdmin()
is_analyst: @isAnalyst()
is_evaluator: @isEvaluator()
is_manager: @isManager()
is_moderator: @isModerator()
is_developer : @isDeveloper()

roleList: -> @roles().join(', ')

Expand Down
40 changes: 40 additions & 0 deletions app/controllers/dashboard/client_errors_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Dashboard::ClientErrorsController < Dashboard::DashboardController
respond_to :json

def index
authorize! :show, ClientError

rendered_admin_template = params["admin_template_needed"] == 'true' ? self.process_admin_template() : nil

errors = ClientError.all.limit(500)

render :json => {:account => current_tenant, :admin_template => rendered_admin_template, :errors => errors}
end

def create
authorize! :create, ClientError

error_params = params['error']

ua = UserAgent.parse(request.user_agent)
more_params = {
:session_id => request.session_options[:id],
:ip => request.remote_ip,
:user_agent => request.user_agent,
:browser => ua.browser,
:version => ua.version.to_s,
:platform => ua.platform,
:user_id => current_user ? current_user.id : nil
}

error_params.update more_params

error = ClientError.create! error_params.permit(:error_type, :trace, :line, :message, :user_id, :session_id, :user_agent, :location, :ip, :browser, :version, :platform)

respond_to do |format|
format.json {render :json => error}
end

end

end
5 changes: 5 additions & 0 deletions app/models/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def initialize(user, current_tenant=nil, session_id=nil, params=nil)
can [:index, :create, :update], Assessable::Request
end

if user.has_role? :developer
can [:index, :create, :update, :show], ClientError
end

if !user.id.nil?
can :create, Assessable::Request do |req|
assessment = req.assessment
Expand Down Expand Up @@ -126,6 +130,7 @@ def initialize(user, current_tenant=nil, session_id=nil, params=nil)
end
end

can :create, ClientError

end
end
Expand Down
2 changes: 2 additions & 0 deletions app/models/client_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class ClientError < ActiveRecord::Base
end
34 changes: 34 additions & 0 deletions app/views/backbone/_admin.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,40 @@
%script{ :type => "text/template", :id => "tpl_dashboard_database"}
%iframe{ :src => rails_admin_path }

%script{ :type => "text/template", :id => "tpl_dashboard_client_errors"}
.m-dashboard-heading
%h2
Javascript and Ajax errors

.m-dashboard-subheading
Client-side errors captured and reported here. Hover for stack trace.

%table.table.table-condensed.table-striped
%tbody
(( errors.each( function(err){ ))
(( var js = err.get('error_type') == 'js'; ))
%tr.client_error{ :title => "{{ err.escape('trace') }}" }
%td.ce_error_type
{{ err.get('error_type') }}

%td.ce_message
{{ err.get('message') }}
%td.ce_location
(( if(!js){ ))
{{ err.get('line') }}:
(( } ))
{{ err.get('location') }}
%td.ce_browser
{{ err.get('browser') }}, {{ err.get('version') }}, {{ err.get('platform') }}
%td.ce_created_at
{{ new Date(err.get('created_at')).toDateString() }}
%td.ce_user
{{ err.get('user_id') }}
%td.ce_session
{{ err.get('session_id') }}
(( }); ))



= render :partial => "backbone/analytics"
= render :partial => "backbone/moderation"
Expand Down
6 changes: 3 additions & 3 deletions app/views/backbone/_auth.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@
I forgot! Email me password instructions.
.m-user-accounts-finish-wrap
%button.m-user-accounts-register-next{:disabled => 'disabled', :type => 'button'}
%button.m-user-accounts-register-next{:disabled => 'disabled', :type => 'button', :'data-target' => "create-account"}
Create my account
(( } ))
.m-user-accounts-finish-wrap
= f.submit "Log me in", :disabled => 'disabled', :class => 'm-user-accounts-login-submit'
= f.submit "Log me in", :disabled => 'disabled', :class => 'm-user-accounts-login-submit', :'data-target' => "login-submit"
Expand Down Expand Up @@ -218,7 +218,7 @@

%script{ :type => "text/template", :id => "tpl_user_paperwork_footer" }

%input{ :name => "commit", :type => "submit", :value => "Create my account!", :class => "ui-state-valid" }
%input{ :name => "commit", :type => "submit", :value => "Create my account!", :class => "ui-state-valid", :'data-target' => "paperwork_complete" }

.m-user-accounts-tos
%span
Expand Down
8 changes: 8 additions & 0 deletions app/views/backbone/_dash.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@
Database
(( } ))

(( if(is_developer) { ))
%hr

%li
%a.m-sidebar_link{:href => "{{Routes.client_error_path()}}", :'data-target' => "client_errors"}
Client errors
(( } ))

- if Rails.env.development?
%li
= link_to 'Tune', '/newrelic', :target => "_blank", :class => 'm-sidebar_link'
Expand Down
6 changes: 5 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def matches?(request)

resources :points, :only => [:create, :update, :destroy, :show]
end



# route all non-ajax requests to home controller, with a few exceptions
get '(*url)' => 'home#index', :constraints => XHRConstraint.new

Expand Down Expand Up @@ -63,6 +64,9 @@ def matches?(request)

#match '/home/study/:category' => "home#study", :via => :post
scope :module => "dashboard" do
match "/report_client_error" => "client_errors#create", :via => :post, :as => :report_client_error
get "/dashboard/client_errors" => "client_errors#index", :as => :client_error

get '/dashboard/admin_template' => "admin#admin_template", :as => :admin_template
#match '/dashboard/application' => "admin#application", :via => :get, :as => :application_settings
get '/dashboard/analytics' => "admin#analytics", :as => :analytics
Expand Down
Loading

0 comments on commit befe858

Please sign in to comment.