जब आपके रेल्स एप्लिकेशन में कोई त्रुटि होती है, तो अपवाद और स्टैक ट्रेस आपको यह ढूंढने में मदद करते हैं कि समस्या कहां हुई। यह जानने के बाद कि क्या हुआ और कहां, हमें यह पता लगाने की जरूरत है कि क्यों हुआ। इस लेख में, हम रेल्स एप्लिकेशन में बग ढूंढने के लिए बैकट्रेस का उपयोग करने पर जाएंगे।
NoMethodError (undefined method `request_uri' for #<URI::Generic >):
app/models/product.rb:8:in `download_image!'
app/controllers/products_controller.rb:5:in `create'
इस उदाहरण अपवाद में, हमें NoMethodError प्राप्त हुआ जिसमें undefined method `request_uri' for #<URI::Generic > संदेश के रूप में था। चूंकि यह अपवाद तुरंत नहीं बताता कि समस्या क्या है, हमें यह पता लगाने के लिए स्टैक ट्रेस का निरीक्षण करना होगा कि क्या हुआ।
app/models/product.rb:8:in `download_image!'
app/controllers/products_controller.rb:5:in `create'
स्टैक ट्रेस को देखते हुए, हम सीखते हैं कि अपवाद Product मॉडल पर download_image! मेथड से उठाया गया था। हम कोड में अपनी जांच जारी रखेंगे, और स्टैक ट्रेस के नीचे अपना रास्ता बनाएंगे ताकि पता लगा सकें कि क्या गलत हो रहा है।
मॉडल खोलने पर पता चलता है कि लाइन 8 (जहां से अपवाद उठाया गया था) Net::HTTP.get(uri) को कॉल करती है, इसलिए ऐसा लगता है कि वह uri वह ऑब्जेक्ट नहीं है जिसकी हम उम्मीद करते हैं।
require 'net/http'
class Product < ApplicationRecord
after_save :download_image!
def download_image!
uri = URI(image_url)
contents = Net::HTTP.get(uri)
File.open("public#{local_image_path}", 'wb') do |file|
file.write contents
end
end
def local_image_path
"/product_#{id}.png"
end
end
चूंकि download_image! मेथड एक after_save कॉलबैक है, हम जानते हैं कि यह एक नए Product को सेव करने के तुरंत बाद निष्पादित होता है।
uri वेरिएबल लाइन 7 पर image_url नामक मेथड से बनाया गया है। यह पता लगाने के लिए कि वह कहां से आता है, हम स्टैक ट्रेस पर एक और नज़र डालेंगे कि Product#create मेथड को ProductsController#create से कॉल किया गया है।
class ProductsController < ApplicationController
def create
@product = Product.new(product_params)
if @product.save
redirect_to @product, notice: 'Product was successfully created.'
else
render :new
end
end
private
def product_params
params.require(:product).permit(:title, :description, :image_url, :price)
end
end
आहा! ProductsController#create product_params के साथ एक नया उत्पाद बनाता है, जिसमें वह :image_url पैरामीटर शामिल है जिसे हम ढूंढ रहे थे।
हम जानते हैं कि image_url एट्रिब्यूट का उपयोग टूटे हुए URI को बनाने के लिए किया जाता है। यदि हम नया उत्पाद बनाते समय image_url फ़ील्ड को खाली छोड़ देते हैं, तो हम समस्या को सफलतापूर्वक पुन: उत्पन्न कर सकते हैं।
इस मामले में, खाली स्ट्रिंग को मान के रूप में URI बनाने का परिणाम URI::Generic ऑब्जेक्ट के बजाय URI::HTTP होता है, क्योंकि यह URL के प्रारूप का निर्धारण नहीं कर सकता। चूंकि पूर्व में #request_uri मेथड नहीं होता, यह Net::HTTP.get से NoMethodError उठाता है।
परियोजना की आवश्यकताओं के आधार पर, यह सुनिश्चित करने के लिए एक वैलिडेशन जोड़ना कि फ़ील्ड खाली नहीं है, समस्या को ठीक कर सकता है। केवल यह मान्य करना कि छवि URL खाली नहीं है, इस कार्यान्वयन के साथ सभी संभावित समस्याओं को ठीक नहीं करेगा (उदाहरण के लिए, जब पास किया गया मान URL नहीं है तो हमें अभी भी एक अपवाद मिलेगा), लेकिन यह एक अच्छी शुरुआत है।
स्टैक ट्रेस का उपयोग करके अपवाद ट्रैक करना
रेल्स के लॉग मुद्दों को डिबग करने का एक शानदार तरीका प्रदान करते हैं। हालांकि उठाए गए अपवाद पहली नज़र में हमेशा बहुत मायने नहीं रखते, कोड द्वारा समस्या तक पहुंचने के लिए उठाए गए चरणों को सावधानीपूर्वक पीछे हटाना आमतौर पर यह पता लगाने का एक शानदार तरीका है कि क्या गलत हुआ, भले ही समस्या का स्रोत आपके ऐप में थोड़ा गहरा दबा हो।
हमें यह जानकर खुशी होगी कि आपको यह लेख कैसा लगा, यदि आपके कोई प्रश्न हैं, और आप आगे क्या पढ़ना चाहेंगे, तो @AppSignal पर हमें बताना सुनिश्चित करें।