एक रेल नियंत्रक में सभी अपवादों को पकड़ो


89

क्या रेल नियंत्रक में सभी अनियंत्रित अपवादों को पकड़ने का एक तरीका है, जैसे:

def delete
  schedule_id = params[:scheduleId]
  begin
    Schedules.delete(schedule_id)
  rescue ActiveRecord::RecordNotFound
    render :json => "record not found"
  rescue ActiveRecord::CatchAll
    #Only comes in here if nothing else catches the error
  end
  render :json => "ok"
end

धन्यवाद

जवाबों:


92
begin
  # do something dodgy
rescue ActiveRecord::RecordNotFound
  # handle not found error
rescue ActiveRecord::ActiveRecordError
  # handle other ActiveRecord errors
rescue # StandardError
  # handle most other errors
rescue Exception
  # handle everything else
  raise
end

38
क्या अपवाद को पकड़ने के लिए नियम नहीं है?
RonLugge

2
लेकिन मैं rescue => eकेवल ब्लॉक में सभी प्रकार कैसे पकड़ सकता हूं ?
मैट्रिक्स

7
@RonLugge यह पूरी तरह से हाथ की स्थिति पर निर्भर करता है। अंगूठे के एक नियम के रूप में "कभी नहीं" लागू करना एक बुरा विचार है।
जस्टिन स्काइल्स

11
@JustinSkiles कैचिंग अपवाद वाक्यविन्यास त्रुटियों को पकड़ लेगा (और संकेतों को भी बाधित करेगा)। मुझे उत्पादन कोड में ऐसा करने के लिए एक अच्छा परिदृश्य दें। सीधे सिग्नल पकड़ना मुझे मिल सकता है, लेकिन आपको स्पष्ट रूप से यह करने की आवश्यकता होगी कि आप सिग्नल हैंडलर बना रहे हैं। बस अपवाद को पकड़ना ... बुरा, बुरा विचार। यहां तक ​​कि उन चीजों को पकड़ता है जिन्हें आपको पकड़ने की कोशिश नहीं करनी चाहिए।
RonLugge

6
कुछ सामान्य मामलों में से एक जहां अपवाद से बचाव के लिए समझदार है वह लॉगिंग / रिपोर्टिंग उद्देश्यों के लिए है, इस मामले में आपको तुरंत अपवाद को फिर से उठाना चाहिए: stackoverflow.com/a/10048406/252346
aelesbao

198

आप एक बचाव_फ्रॉम विधि को भी परिभाषित कर सकते हैं।

class ApplicationController < ActionController::Base
  rescue_from ActionController::RoutingError, :with => :error_render_method

  def error_render_method
    respond_to do |type|
      type.xml { render :template => "errors/error_404", :status => 404 }
      type.all  { render :nothing => true, :status => 404 }
    end
    true
  end
end

आपका लक्ष्य क्या है, इसके आधार पर, आप प्रति-नियंत्रक आधार पर अपवादों को नहीं संभालने पर भी विचार कर सकते हैं। इसके बजाय, अपवादों की प्रतिक्रियाओं को लगातार प्रबंधित करने के लिए अपवाद_हैंडलर मणि जैसी किसी चीज़ का उपयोग करें । एक बोनस के रूप में, यह दृष्टिकोण मिडलवेयर लेयर पर होने वाले अपवादों को भी हैंडल करेगा, जैसे कि रिक्वेस्ट पार्सिंग या डेटाबेस कनेक्शन एरर जो आपके एप्लिकेशन को नहीं दिखता है। Exception_notifier मणि भी ब्याज की हो सकती है।


4
यह और भी आसान है क्योंकि यह DRY तरीके से अपवादों को पकड़ने की अनुमति देता है।
m33lky

और अगर मैं कोई params के साथ बचाव_फ्रेम का उपयोग करता हूं? क्या वह बचाव के समान व्यवहार करेगा? सभी त्रुटियों को पकड़ने?
मिनोहिम खुद

2
क्या यह बुरा अभ्यास नहीं है rescue_from Exception? मेरी समझ है कि यह से बचाव के लिए बेहतर है StandardError, इसलिए तरह बातें SyntaxErrorऔर LoadErrorपकड़ा नहीं कर रहे हैं।
लोबाती

हाँ, यह 'अपवाद' को बचाने के लिए बुरा रूप है। Avdi ग्रिम की "असाधारण रूबी" कारणों से देखें कि क्यों समस्याग्रस्त हो सकता है।
मिडवायर

34

आप प्रकार से अपवादों को पकड़ सकते हैं:

rescue_from ::ActiveRecord::RecordNotFound, with: :record_not_found
rescue_from ::NameError, with: :error_occurred
rescue_from ::ActionController::RoutingError, with: :error_occurred
# Don't resuce from Exception as it will resuce from everything as mentioned here "http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby" Thanks for @Thibaut Barrère for mention that
# rescue_from ::Exception, with: :error_occurred 

protected

def record_not_found(exception)
  render json: {error: exception.message}.to_json, status: 404
  return
end

def error_occurred(exception)
  render json: {error: exception.message}.to_json, status: 500
  return
end

2
Exceptionसीधे बचाव से सावधान ; देखें stackoverflow.com/questions/10048173/…
थिबुत बर्रे

10

rescue किसी भी तर्क के साथ कोई त्रुटि नहीं होगी।

तो, आप चाहते हैं:

def delete
  schedule_id = params[:scheduleId]
  begin
    Schedules.delete(schedule_id)
  rescue ActiveRecord::RecordNotFound
    render :json => "record not found"
  rescue
    #Only comes in here if nothing else catches the error
  end
  render :json => "ok"
end

8
बासी सवाल, लेकिन यह जवाब गलत है। बिना तर्क के बचाव केवल StandardError robots.thoughtbot.com/rescue-standarderror-not-exception
Keith Gaddis

0

वास्तव में, यदि आप वास्तव में सब कुछ पकड़ना चाहते हैं , तो आप बस अपना स्वयं का अपवाद ऐप बनाते हैं, जो कि आप उस व्यवहार को अनुकूलित करते हैं जो आमतौर पर PublicException मिडलवेयर द्वारा नियंत्रित किया जाता है: https://github.com/rails/rails/blob/4-2 -stable / actionpack / lib / action_dispatch / मिडलवेयर / public_exceptions.rb

अन्य उत्तरों का एक समूह आपके लिए ऐसा करने वाले रत्नों को साझा करता है, लेकिन वास्तव में कोई कारण नहीं है कि आप सिर्फ उन्हें देख सकते हैं और इसे स्वयं कर सकते हैं।

एक चेतावनी: सुनिश्चित करें कि आप कभी भी अपने अपवाद हैंडलर में अपवाद नहीं उठाते हैं। अन्यथा आपको एक बदसूरत FailsAFE_RESPONSE https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/show_nception.rb#L4-L22 मिलता है

BTW, नियंत्रक में व्यवहार बचाव योग्य से आता है: https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.