2013-03-17 6 views
11

रेल 4 एक अपवाद ActionDispatch :: ParamsParser :: ParseError अपवाद कहते हैं लेकिन जब से मिडलवेयर ढेर में अपनी यह प्रतीत होता है यह सामान्य में बचाया नहीं किया जा सकता नियंत्रक पर्यावरण। एक जेसन एपीआई एप्लिकेशन में मैं एक मानक त्रुटि प्रारूप के साथ जवाब देना चाहता हूँ।कैसे रेल में ActionDispatch :: ParamsParser :: ParseError से बचाव करने के लिए 4

यह gist मध्यस्थता को रोकने और प्रतिक्रिया देने के लिए एक रणनीति दिखाता है। इस पद्धति के बाद मेरे पास है:

application.rb:

module Traphos 
    class Application < Rails::Application 
    .... 
    config.middleware.insert_before ActionDispatch::ParamsParser, "JSONParseError" 
end 
end 

और मिडलवेयर है:

class JSONParseError 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    begin 
     @app.call(env) 
    rescue ActionDispatch::ParamsParser::ParseError => e 
     [422, {}, ['Parse Error']] 
    end 
    end 
end 

मैं मिडलवेयर मैं (कल्पना) के बिना अपने परीक्षण चलाते हैं :

Failures: 

    1) Photo update attributes with non-parseable json 
    Failure/Error: patch update_url, {:description => description}, "CONTENT_TYPE" => content_type, "HTTP_ACCEPT" => accepts, "HTTP_AUTHORIZATION" => @auth 
    ActionDispatch::ParamsParser::ParseError: 
     399: unexpected token at 'description=Test+New+Description]' 

जो वही है जो मैं उम्मीद करता हूं (पारस्परिक रूप से मैं बचाव नहीं कर सकता)।

अब केवल परिवर्तन के साथ ऊपर मिडलवेयर में जोड़ने के लिए:

2) Photo update attributes with non-parseable json 
    Failure/Error: response.status.should eql(422) 

     expected: 422 
      got: 200 

और लॉग मानक नियंत्रक कार्रवाई निष्पादित किया जा रहा है और एक सामान्य प्रतिक्रिया लौटने (हालांकि बाद से यह कोई पैरामीटर प्राप्त नहीं किया था पता चलता यह कुछ भी अद्यतन नहीं किया था)।

मेरे सवालों का:

  1. कैसे ParseError से बचाव और एक कस्टम प्रतिक्रिया लौट सकते हैं। ऐसा लगता है कि मैं सही रास्ते पर हूं लेकिन वहां काफी नहीं है।

  2. मैं काम नहीं कर सकता, जब अपवाद उठाया जाता है और बचाया जाता है, तो नियंत्रक कार्रवाई अभी भी बढ़ जाती है।

मदद की बहुत सराहना, --Kip

+0

क्या कोई अन्य मिडलवेयर है जो रिटर्न स्थिति बदलता है? क्या आपने प्रिये या कुछ के साथ कुछ डिबगिंग किया था? – phoet

उत्तर

6

बाहर कर देता है कि आगे मिडलवेयर ढेर अप, ActionDispatch :: ShowExceptions एक अपवाद अनुप्रयोग के साथ विन्यस्त किया जा सकता।

module Traphos 
    class Application < Rails::Application 
    # For the exceptions app 
    require "#{config.root}/lib/exceptions/public_exceptions" 
    config.exceptions_app = Traphos::PublicExceptions.new(Rails.public_path) 
    end 
end 

रेल पर भारी आधारित एक प्रदान की मैं अब उपयोग कर रहा हूँ:

module Traphos 
    class PublicExceptions 
    attr_accessor :public_path 

    def initialize(public_path) 
     @public_path = public_path 
    end 

    def call(env) 
     exception = env["action_dispatch.exception"] 
     status  = code_from_exception(env["PATH_INFO"][1..-1], exception) 
     request  = ActionDispatch::Request.new(env) 
     content_type = request.formats.first 
     body   = {:status => { :code => status, :exception => exception.class.name, :message => exception.message }} 
     render(status, content_type, body) 
    end 

    private 

    def render(status, content_type, body) 
     format = content_type && "to_#{content_type.to_sym}" 
     if format && body.respond_to?(format) 
     render_format(status, content_type, body.public_send(format)) 
     else 
     render_html(status) 
     end 
    end 

    def render_format(status, content_type, body) 
     [status, {'Content-Type' => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}", 
       'Content-Length' => body.bytesize.to_s}, [body]] 
    end 

    def render_html(status) 
     found = false 
     path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale 
     path = "#{public_path}/#{status}.html" unless path && (found = File.exist?(path)) 

     if found || File.exist?(path) 
     render_format(status, 'text/html', File.read(path)) 
     else 
     [404, { "X-Cascade" => "pass" }, []] 
     end 
    end 

    def code_from_exception(status, exception) 
     case exception 
     when ActionDispatch::ParamsParser::ParseError 
     "422" 
     else 
     status 
     end 
    end 
    end 
end 

एक परीक्षण वातावरण में उसका उपयोग करने config चर स्थापित करने की आवश्यकता है (अन्यथा आप मानक अपवाद विकास और परीक्षण में निपटने मिल) । तो परीक्षण करने के लिए मैं (सिर्फ प्रमुख भागों के लिए संपादित) है

describe Photo, :type => :api do 
    context 'update' do 
    it 'attributes with non-parseable json' do 

     Rails.application.config.consider_all_requests_local = false 
     Rails.application.config.action_dispatch.show_exceptions = true 

     patch update_url, {:description => description} 
     response.status.should eql(422) 
     result = JSON.parse(response.body) 
     result['status']['exception'].should match(/ParseError/) 

     Rails.application.config.consider_all_requests_local = true 
     Rails.application.config.action_dispatch.show_exceptions = false 
    end 
    end 
end 

के रूप में मैं एक सार्वजनिक एपीआई तरह से की जरूरत है कौन करता है और किसी भी अन्य अपवाद मैं अनुकूलित करने के लिए चुन सकते हैं के लिए अनुकूल है।

0

यह आलेख (2013 से भी) thoughtbot इस विषय को भी शामिल करता है।उन्होंने आपकी प्रतिक्रिया केवल इस मिडलवेयर सेवा के अंदर रखी है यदि आपने जेसन

if env['HTTP_ACCEPT'] =~ /application\/json/ 
    error_output = "There was a problem in the JSON you submitted: #{error}" 
    return [ 
     400, { "Content-Type" => "application/json" }, 
     [ { status: 400, error: error_output }.to_json ] 
    ] 
else 
raise error 
end 
संबंधित मुद्दे