Skip to content

Instantly share code, notes, and snippets.

@TheRusskiy
Created January 7, 2016 18:10
Show Gist options
  • Save TheRusskiy/0689762fa6de2418c58b to your computer and use it in GitHub Desktop.
Save TheRusskiy/0689762fa6de2418c58b to your computer and use it in GitHub Desktop.
for blogpost about error handling
$.ajax({
dataType: "json",
url: "/stuff/" + id + "/do_something",
data: {x: x, y: y}
}).done(function(response){
window.alert("Yay!");
}).fail(function(error){
// even if no message is provided we should tell a user that something went wrong
errorMessage = (error.responseJSON && error.responseJSON.message) || "Some error occurred!"
window.alert(errorMessage);
})
def handle_exceptions *exceptions
# if nothing is passed then handle the most basic error class Exception
exceptions << Exception if exceptions.empty?
begin
yield # execute code passed into the method
rescue *exceptions => exception # look for specified exceptions
# depending on the request format we should perform different actions
respond_to do |format|
error_message = exception.respond_to?(:message) ? exception.message : "Some error occurred!"
format.json do
render json: { # pass exception's name and a message
exception: exception.class.name,
message: error_message
}, status: 400
end
format.html do
# if this request came from some page then redirect back
# if no request referrer specified then redirect to user's home page
path = (request.referer && :back) || root_path_for(current_user)
redirect_to path, alert: error_message
end
format.js do
# if this was Javascript request then do a simplete window.alert
# window.alert can be replaced with more sophisticated code
render inline: "window.alert(#{error_message.to_json})".html_safe
end
end
end
end
def handle_exceptions *exceptions
# if nothing is passed then handle the most basic error class Exception
exceptions << Exception if exceptions.empty?
# if string was passed let's consider it a redirect path
path = exceptions.select{|e| e.is_a? String}.first
exceptions.reject!{|e| e.is_a? String}
begin
yield # execute code passed into the method
rescue *exceptions => exception # look for specified exceptions
# depending on the request format we should perform different actions
respond_to do |format|
error_message = exception.respond_to?(:message) ? exception.message : "Some error occurred!"
# if it's going to help our javascript code let's pass some additional data
data = exception.respond_to?(:data) ? exception.data : {}
format.json do
render json: { # pass exception's name and a message
exception: exception.class.name,
data: data
message: error_message
}, status: 400
end
format.html do
# if this request came from some page then redirect back
# if no request referrer specified then redirect to user's home page
if path.nil?
path = (request.referer && :back) || root_path_for(current_user)
end
redirect_to path, alert: error_message
end
format.js do
# if this was Javascript request then do a simplete window.alert
# window.alert can be replaced with more sophisticated code
render inline: "window.alert(#{error_message.to_json})".html_safe
end
end
end
end
# I always forget if it's errors or exceptions, so let's make it respond to both
alias_method :handle_errors, :handle_exceptions
# controller
class StuffController < ApplicationController
def some_action
handle_exceptions UserError, stuff_page_path(params[:id]) do
stuff = Stuff.find(params[:id])
stuff.do_something(params[:x], params[:y])
render json: {stuff: stuff.in_json}, status: 201 }
end
end
end
# model
class Stuff < ActiveRecord::Base
def do_something x, y
if x != y
raise UserError.new("X has to equal Y!")
end
end
end
class UserError < StandardError
attr_accessor :data
def initialize message, data = nil
@data = data
super(message)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment