handles_errors.rb 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. module ApplicationController::HandlesErrors
  2. extend ActiveSupport::Concern
  3. included do
  4. rescue_from StandardError, with: :internal_server_error
  5. rescue_from ExecJS::RuntimeError, with: :internal_server_error
  6. rescue_from ActiveRecord::RecordNotFound, with: :not_found
  7. rescue_from ActiveRecord::StatementInvalid, with: :unprocessable_entity
  8. rescue_from ActiveRecord::RecordInvalid, with: :unprocessable_entity
  9. rescue_from ArgumentError, with: :unprocessable_entity
  10. rescue_from Exceptions::UnprocessableEntity, with: :unprocessable_entity
  11. rescue_from Exceptions::NotAuthorized, with: :unauthorized
  12. end
  13. def not_found(e)
  14. logger.error e
  15. respond_to_exception(e, :not_found)
  16. http_log
  17. end
  18. def unprocessable_entity(e)
  19. logger.error e
  20. respond_to_exception(e, :unprocessable_entity)
  21. http_log
  22. end
  23. def internal_server_error(e)
  24. logger.error e
  25. respond_to_exception(e, :internal_server_error)
  26. http_log
  27. end
  28. def unauthorized(e)
  29. error = humanize_error(e.message)
  30. response.headers['X-Failure'] = error.fetch(:error_human, error[:error])
  31. respond_to_exception(e, :unauthorized)
  32. http_log
  33. end
  34. private
  35. def respond_to_exception(e, status)
  36. status_code = Rack::Utils.status_code(status)
  37. respond_to do |format|
  38. format.json { render json: humanize_error(e.message), status: status }
  39. format.any do
  40. errors = humanize_error(e.message)
  41. @exception = e
  42. @message = errors[:error_human] || errors[:error] || param[:message]
  43. @traceback = !Rails.env.production?
  44. file = File.open(Rails.root.join('public', "#{status_code}.html"), 'r')
  45. render inline: file.read, status: status
  46. end
  47. end
  48. end
  49. def humanize_error(error)
  50. data = {
  51. error: error
  52. }
  53. case error
  54. when /Validation failed: (.+?)(,|$)/i
  55. data[:error_human] = $1
  56. when /(already exists|duplicate key|duplicate entry)/i
  57. data[:error_human] = 'Object already exists!'
  58. when /null value in column "(.+?)" violates not-null constraint/i
  59. data[:error_human] = "Attribute '#{$1}' required!"
  60. when /Field '(.+?)' doesn't have a default value/i
  61. data[:error_human] = "Attribute '#{$1}' required!"
  62. when 'Exceptions::NotAuthorized'
  63. data[:error] = 'Not authorized'
  64. data[:error_human] = data[:error]
  65. end
  66. if Rails.env.production? && data[:error_human].present?
  67. data[:error] = data.delete(:error_human)
  68. end
  69. data
  70. end
  71. end