Skip to content

Instantly share code, notes, and snippets.

@dudo
Created September 16, 2019 06:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dudo/9c61389c52b8f8f929fafee4e44b7f8a to your computer and use it in GitHub Desktop.
Save dudo/9c61389c52b8f8f929fafee4e44b7f8a to your computer and use it in GitHub Desktop.
module FastJsonapi
module ErrorSerializer
extend ActiveSupport::Concern
included do
include FastJsonapi::ObjectSerializer
attr_accessor :with_root_key
set_id :title
def initialize(resource, options = {})
super
@with_root_key = options[:with_root_key] != false
end
def hash_for_one_record
serialized_hash = super.dig(:data, :attributes)
if with_root_key
{ errors: serialized_hash }
else
serialized_hash
end
end
def hash_for_collection
serialized_hash = super[:data]&.map { |err| err[:attributes] }
if with_root_key
{ errors: serialized_hash }
else
serialized_hash
end
end
end
end
end
class ErrorSerializer
include FastJsonapi::ErrorSerializer
attributes :title, :detail, :code, :status
attribute :source do |object|
object.serializer_source
end
end
module HasErrorResponse
extend ActiveSupport::Concern
included do
rescue_from StandardError, with: :render_exception
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActionController::RoutingError, with: :not_found
rescue_from Pundit::NotAuthorizedError, with: :unauthorized
end
private
def unauthorized(exception)
render_exception(exception, code: :unauthorized)
end
def not_found(exception)
render_exception(exception, code: :not_found)
end
def render_exception(exception, code: :internal_server_error)
status = Rack::Utils.status_code(code).to_s
object = OpenStruct.new(
id: SecureRandom.uuid,
title: I18n.t("#{status[0]}xx.title", scope: 'exceptions', default: :default),
detail: exception.to_s.humanize,
code: code,
status: status
)
render json: ErrorSerializer.new(object), status: code
end
def render_errors(errors, code: :unprocessable_entity)
objects = errors.as_json(full_messages: true).map do |attribute, messages|
OpenStruct.new(
id: SecureRandom.uuid,
title: I18n.t(code, scope: 'errors', default: :default),
detail: messages.to_sentence,
code: attribute,
status: Rack::Utils.status_code(code).to_s
)
end
render json: ErrorSerializer.new(objects), status: code
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment