2011-09-08 31 views
12

मैं रेल 3 में अज्ञात कार्यवाही गलती, पता चलता है कि विकास और उत्पादन पर 404.html पर "अज्ञात कार्रवाई" त्रुटि को पकड़ने के लिए चाहते हैं के लिए। मैंने अपने 0Cहैंडलर को मेरे एप्लिकेशन कंट्रोलर (और वास्तविक नियंत्रक पर भी, केवल मामले में) डालने का प्रयास किया लेकिन मुझे अभी भी बदसूरत त्रुटि दिखाई दे रही है।पकड़ने अज्ञात कार्रवाई कस्टम 404

मैं 404 पर कस्टम सामान है, और इसे सादे .html फ़ाइल नहीं हो सकता।

मेरे मार्ग:

match '/user/:id/:action', controller: 'users' 

यूआरएल मैं तक पहुँचने हूँ: /user/elado/xxx

rescue_from कोड:

rescue_from AbstractController::ActionNotFound, :with => :action_not_found 

def action_not_found 
    render text: "action_not_found" 
end 

ब्राउज़र में त्रुटि:

Unknown action 

The action 'xxx' could not be found for UsersController 

और कंसोल में:

Started GET "/user/elado/xxx" for 127.0.0.1 at 2011-09-07 19:16:27 -0700 

AbstractController::ActionNotFound (The action 'xxx' could not be found for UsersController): 

भी rescue_from ActionController::UnknownAction की कोशिश की।

कोई सुझाव? धन्यवाद!

उत्तर

14

rescue_from थोड़ा टूट गया था जब रेल 3 बाहर आया था (अभी भी 3.1 में भी टूट)। असल में आप नहीं कर सकते:

rescue_from ActionController::RoutingError 

अब और। here देखें।

समाधान, अब के लिए, hamiltop क्या सिफारिश की गई है। अपने "रूटिंग त्रुटि" मार्ग पर जाने वाले सभी मार्गों को पकड़ें। सुनिश्चित करें कि आप इसे अपनी कॉन्फ़िगरेशन \ path.rb फ़ाइल के अंत में डाल दें ताकि इसे अंतिम संसाधित किया जा सके।

# Any routes that aren't defined above here go to the 404 
match "*a", :to => "application#routing_error" 

def routing_error 
    render "404", :status => 404 
end 

नोट: इस विधि से एक बड़ी खामी है। यदि आप जैकेट या डेविस जैसे इंजन का उपयोग करते हैं तो सभी मार्ग रेलवे इंजन के मार्गों को अनदेखा कर देगा।

यदि आप ऐसे इंजन का उपयोग नहीं कर रहे हैं जिसके पास अपने मार्ग हैं तो आपको ठीक होना चाहिए। हालांकि, यदि आप ऐसे इंजन का उपयोग करते हैं जो अपने मार्गों को परिभाषित करता है तो @ arikfr का उत्तर देखें।

+0

निम्न लिंक कुछ अच्छी अंतर्दृष्टि प्रदान करता है, यह भी एक उदाहरण देता है कि अपवाद को बेहतर तरीके से कैसे संभालना है (3.2 या उच्चतर)। http://geekmonkey.org/articles/29-exception-applications-in-rails-3-2 – Agustin

0

क्या आपने सभी मार्गों को पकड़ने की कोशिश की है?

http://railscasts.com/episodes/46-catch-all-route

वाइल्डकार्ड मार्ग है कि आप का उपयोग कर मौजूदा कर रहे हैं एक बुरा आइडिया (टीएम) है।

मैं मार्गों आप ध्यान परिभाषित करने, और फिर routes.rb की अंतिम पंक्ति के रूप में एक कैचऑल कर की सिफारिश करेंगे (मार्गों पहले routes.rb ट्रम्प बाद में परिभाषाओं में परिभाषित)। फिर आप जो भी पेज चाहते हैं उसे प्रस्तुत कर सकते हैं (और 404 स्टेटस कोड निर्दिष्ट करें)।

संपादित करें: तुम सच में ... अपने वर्तमान दृष्टिकोण का उपयोग करने (हालांकि यह लगता है जैसे कि यह पदावनत किया जा सकता है) चाहते हैं

डीईएफ़ rescue_action (अपवाद) मामले अपवाद ActionNotFound, UnknownAction तो # इन संभाल जब अपवाद यहाँ बाकी सुपर अंत अंत

+0

मैं वास्तव में किसी अन्य चीज़ के लिए सभी मार्ग पकड़ने का उपयोग कर रहा हूं, लेकिन मैं वास्तव में केवल क्रिया के बजाय वास्तविक उपलब्ध क्रिया जोड़ सकता हूं। धन्यवाद। लेकिन क्या मैं 'rescue_from' के साथ कुछ गलत कर रहा हूं? ऐसा लगता है कि यह काम करना चाहिए ... – elado

+0

धन्यवाद, हालांकि 'def rescue_action (अपवाद); मामला अपवाद; जब ActionController :: अज्ञात क्रिया, सार नियंत्रक :: ActionNotFound तब टेक्स्ट प्रस्तुत करें: "404"; अन्यथा टेक्स्ट प्रस्तुत करें: "अन्य अपवाद"; समाप्त; अनुप्रयोग नियंत्रक या उपयोगकर्ता नियंत्रक में अंत 'काम नहीं किया। – elado

9

404 इरॉस (जैसा कि @ सेठ जैक्सन सुझाव दिया गया है) को संभालने के लिए सभी मार्गों को पकड़ने का एक बड़ा दोष है: यदि आप किसी भी रेल इंजन का उपयोग करते हैं जो अपने मार्गों (जैसे जैमिट) को परिभाषित करता है तो उनके मार्गों को अनदेखा कर दिया जाएगा।

बेहतर और अधिक अनुपालन समाधान एक रैक मिडलवेयर का उपयोग करना होगा जो 404 त्रुटियों को पकड़ लेगा। मेरी परियोजनाओं में से एक में, मैंने ऐसे रैक मिडलवेयर को कार्यान्वित किया है जो इन त्रुटियों को हॉपटोड को रिपोर्ट करता है। मैंने इस पर अपना कार्यान्वयन किया है: https://github.com/vidibus/vidibus-routing_error, लेकिन 404 त्रुटि को संभालने के लिए फिर से मेरे रेल ऐप को आविष्कार करने की बजाय, मैं इसे रैक मिडलवेयर में करता हूं और nginx को 404 पेज दिखाने देता हूं।

+0

अच्छी पकड़। मैं इसके बारे में भूल गया था। मैंने इसे अन्य इंजनों (डेविस) के साथ भी देखा है। मैं इसके बारे में एक उत्तर मेरे जवाब में जोड़ दूंगा। –

1

तुम सच में एक नियंत्रक में AbstractController::ActionNotFound को बचाने के लिए चाहते हैं, आप कुछ इस तरह की कोशिश कर सकते हैं:

class UsersController < ApplicationController 

    private 

    def process(action, *args) 
    super 
    rescue AbstractController::ActionNotFound 
    respond_to do |format| 
     format.html { render :404, status: :not_found } 
     format.all { render nothing: true, status: :not_found } 
    end 
    end 


    public 

    # actions must not be private 

end 

यह उपरोक्त कि AbstractController::ActionNotFound को जन्म देती है (source देखें) AbstractController::Base की process विधि।

संबंधित मुद्दे