web-dev-qa-db-fra.com

Comment renvoyer les codes d'erreur HTTP corrects de Ruby on Rails application

J'ai une application Web RoR 3.0 qui agit comme un fournisseur d'API OAuth. Maintenant, dans l'API, je voudrais renvoyer les codes d'erreur HTTP corrects au consommateur d'API. Comment dois-je procéder?

Voici un exemple:

def destroy_oauth
    @item = Item.find(params[:id])
    if([email protected]? && @item.user_id == current_user.id)
        @item.destroy
        respond_to do |format|
                format.js
                format.xml
        end
    else
        raise ActionController::RoutingError.new('Forbidden')
    end
end

Donc, en cas d'erreur, j'essaie de renvoyer le code interdit 403. Pourtant, en exécutant cela, je reçois toujours 404 Not Found retourné. Comment renvoyer le bon code?

Ou est-ce quelque chose de configurable en quelque sorte sur le serveur Web?

30
Alexander Savin

Vous devez rendre la page avec un état correct.

render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)
43
Sandip Ransing

Lorsque vous donnez simplement un code d'état et qu'il n'y a pas de corps, un moyen pratique est

head 403

Cette méthode accepte également les noms symboliques des codes d'état, tels que

head :forbidden
54
Frederick Cheung

Selon ActionController :: Head docs il suffit d'utiliser ce modèle dans les actions

  return head([status]) if/unless [some condition here]

Exemple:

  return head(:gone) if @record.deleted?
  return head(:forbidden) unless @user.owns?(@record)

return est utilisé pour s'assurer qu'aucun code restant dans l'action ne sera exécuté.

12
gertas

vous pouvez utiliser

:status =>500

Mais, par défaut Rails s'occupe du rendu du type d'erreur lui-même.

Les pages par défaut des erreurs se trouvent dans le répertoire public. 500.html, 404.html etc.

Pour plus d'informations sur :status, comment l'utiliser cliquez ici

1
Manish Shrivastava

Je pense que vous avez deux problèmes ici: le premier est que votre ligne @item = Item.find(params[:id]) soulève 404 et l'exécution n'arrive jamais à l'endroit voulu (instruction if). Deuxièmement, vous soulevez des exceptions et ne les attrapez jamais. Essayer:

def destroy_oauth
   begin
     @item = Item.find(params[:id])
     if([email protected]? && @item.user_id == current_user.id)
       @item.destroy
       respond_to do |format|
          format.js
          format.xml
       end
     else
       raise ActionController::RoutingError.new('Forbidden')
     end
   rescue ActiveRecord::ResourceNotFound
     redirect_to :action => 'not_found', :status => 404 # do whatever you want here
   rescue ActionController::RoutingError
     redirect_to :action => 'forbidden', :status => 403 # do whatever you want here
   end
 end

Quelque chose dans ce sens, mais vous avez également mentionné que vous construisez l'API, donc lorsque vous récupérez l'erreur, vous souhaiterez peut-être afficher les informations d'erreur xml. Quelque chose comme:

# in application_controller.rb
rescue_from ActionController::RoutingError, :with => :render_forbidden_error

private

def render_forbidden_error(e)
  render :status => e.status, :xml => e
end

Bonne chance. Udachi.

1
Simon Bagreev