Je suis assez nouveau pour Rails et le développement de l'API back-end, alors excusez-moi si j'utilise un concept ou non. En ce moment, j'essaie de refactoriser une grande quantité de code de gestion des erreurs conditionnelles qui est réparti autour de la base de code et d'utiliser une liste explicite d'exceptions sauvées qui est mélangée dans le contrôleur API en l'incluant dans un module. Cela me permettra d'attacher des codes personnalisés, mais arbitraires, à chaque exception interceptée, à condition que nous utilisions les alternatives bang pour les méthodes d'enregistrement actives, et que le code de gestion des erreurs puisse vivre au même endroit. Jusqu'à présent, pour le module de gestion des erreurs, j'ai quelque chose comme ceci:Meilleure façon d'effectuer la gestion des erreurs à l'aide de modules dans Rails?
# app/lib/error/error_handling.rb
module Error
module ErrorHandling
def self.included(klass)
klass.class_eval do
rescue_from ActiveRecord::RecordNotFound do |e|
respond(:record_not_found, 404, e.to_s)
end
rescue_from ActiveRecord::ActiveRecordError do |e|
respond(e.error, 422, e.to_s)
end
rescue_from ActiveController::ParameterMissing do |e|
response(:unprocessable_entitry, 422, e.to_s)
end
rescue_from ActiveModel::ValidationError do |e|
response(e.error, 422, e.to_s)
end
rescue_from CustomApiError do |e|
respond(e.error, e.status, e.message.to_s)
end
rescue_from CanCan::AccessDenied do
respond(:forbidden, 401, "current user isn't authorized for that")
end
rescue_from StandardError do |e|
respond(:standard_error, 500, e.to_s)
end
end
end
private
def respond(_error, _status, _message)
render "layouts/api/errors", status: _status
end
end
end
Où layouts/api/errors
est une vue construite en utilisant JBuilder. Dans le ApiController
nous avons:
# app/controllers/api/api_controller.rb
module Api
class ApiController < ApplicationController
include Error::ErrorHandling
attr_reader :active_user
layout "api/application"
before_action :authenticate_by_token!
before_action :set_uuid_header
respond_to :json
protect_from_forgery with: :null_session
skip_before_action :verify_authenticity_token, if: :json_request?
private
...
end
Malheureusement, cela ne semble pas fonctionner. L'exécution de tests montre que les méthodes privées ne sont pas du tout chargées et sont considérées comme non définies!
Pour être ici plus précis, sont les erreurs émises:
uninitialized constant Error::ErrorHandling::ActiveController
et
undefined local variable or method `active_user' for Api::FooController
Où active_user
est un attribut qui est placé à l'intérieur d'une variable d'instance par une méthode appelée set_active_user
. Ce qui n'est évidemment pas appelé.
Cependant, le module ErrorHandling
est en cours d'évaluation. Comment cela pourrait-il être? Suis-je mal orthographié ou quelque chose?
Merci d'avoir lu.
Pouvez-vous préciser quelles méthodes privées sont indéfinies? Le dans le contrôleur ou le dans le module? Si possible, un stacktrace pourrait aussi aider. – ulferts
J'ai mis à jour le post. Comme mentionné, le module est en train d'être évalué mais j'appuie sur l'erreur '' constantial unitialized'' et la 'variable ou méthode locale indéfinie'' dans le contrôleur api, quand ils sont réellement définis. Peut-être l'erreur dans le module empêche-t-elle d'évaluer le code en dessous de 'include '? – dynsne
Je ne pouvais fournir qu'un pointeur de base concernant le problème de la "méthode non définie". Si vous montrez le code qui déclenche l'erreur, je pourrais vous proposer une aide plus spécifique. – ulferts