রেলের সাথে কাজ করার বিষয়ে একটি চমৎকার জিনিস হল যে যখন বিকাশে কিছু ভুল হয়ে যায়, আপনি সত্যিই একটি চমৎকার ত্রুটির বিস্তারিত পৃষ্ঠা পান। আপনার অ্যাপের সাথে প্রাসঙ্গিক অংশগুলি হাইলাইট করে আপনি একটি চমৎকার ব্যাকট্রেস পাবেন। আপনি পোস্ট করা প্যারামগুলি দেখতে পারেন, সেইসাথে পরিবেশ এবং সেশন ভেরিয়েবলগুলি পরিদর্শন করতে পারেন৷
৷আজ আমরা এই অভিনব ত্রুটি পৃষ্ঠাগুলি কিভাবে কাজ করে তা দেখতে যাচ্ছি৷
ক্র্যাকিং ওপেন অ্যাকশনপ্যাক
আজকে আমরা যে ফাইলটি নিয়ে সবচেয়ে বেশি উদ্বিগ্ন হতে যাচ্ছি তা হল actionpack/lib/action_dispatch/middleware/debug_exceptions.rb। এটি সেই বিকাশ মোড ত্রুটি পৃষ্ঠাগুলি প্রদর্শন করার ক্ষেত্রে বেশিরভাগ ভারী উত্তোলন করে। প্রোডাকশন মোড এরর স্ক্রীন কোথা থেকে আসে সে সম্পর্কে আপনি যদি আগ্রহী হন, তাহলে public_exceptions.rb দেখুন।
র্যাক মিডলওয়্যার
৷আপনি যদি র্যাক মিডলওয়্যারের সাথে পরিচিত না হন তবে ধারণাটি সহজ। এটি আপনাকে HTTP অনুরোধগুলি আপনার অ্যাপে পৌঁছানোর আগে বাধা দিতে এবং ব্যবহারকারীর কাছে ফিরে যাওয়ার আগে অ্যাপের আউটপুটকে বাধা দিতে দেয়৷
এখানে একটি সাধারণ মিডলওয়্যার যা আকর্ষণীয় কিছু করে না৷
৷class MyMiddleware
def initialize(app)
@app = app
end
def call(env)
@app.call(env)
end
end
র্যাক মিডলওয়্যারের মাধ্যমে সমস্ত ব্যতিক্রম উদ্ধার করা
@app.call() কল করার ফলে আপনার অ্যাপে যে কোনো ব্যতিক্রম ঘটে। তাই একটি র্যাক অ্যাপে সমস্ত ব্যতিক্রম উদ্ধার করা মিডলওয়্যারে একটি রেসকিউ ক্লজ যোগ করার মতোই সহজ৷
def call(env)
@app.call(env)
rescue StandardError => exception
# this is a method we have to provide to generate the exception page
render_exception(env, exception)
end
কল পদ্ধতি থেকে ফিরে আসা যেকোনো কিছুকে সাধারণ ওয়েব পৃষ্ঠা হিসাবে বিবেচনা করা হবে। তাই render_exception দ্বারা প্রত্যাবর্তিত বিষয়বস্তু মূল প্রতিক্রিয়া প্রতিস্থাপন করে।
ব্যতিক্রম রেন্ডার করা
আমি ActionDispatch::DebugExceptions থেকে render_exception পদ্ধতিটি উদ্ধৃত করেছি। আপনি দেখতে পাচ্ছেন, এটি কেবল ব্যতিক্রম থেকে প্রাসঙ্গিক ডেটা টেনে আনে এবং এটিকে একটি ERB টেমপ্লেটে ফিড করে।
def render_exception(env, exception)
wrapper = ExceptionWrapper.new(env, exception)
log_error(env, wrapper)
if env['action_dispatch.show_detailed_exceptions']
request = Request.new(env)
template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
request: request,
exception: wrapper.exception,
application_trace: wrapper.application_trace,
framework_trace: wrapper.framework_trace,
full_trace: wrapper.full_trace,
routes_inspector: routes_inspector(exception),
source_extract: wrapper.source_extract,
line_number: wrapper.line_number,
file: wrapper.file
)
file = "rescues/#{wrapper.rescue_template}"
if request.xhr?
body = template.render(template: file, layout: false, formats: [:text])
format = "text/plain"
else
body = template.render(template: file, layout: 'rescues/layout')
format = "text/html"
end
render(wrapper.status_code, body, format)
else
raise exception
end
end
def render(status, body, format)
[status, {'Content-Type' => "#{format}; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
end
অন্যান্য ব্যবহার
আপনি ব্যতিক্রম সহ অনেক আকর্ষণীয় জিনিস করতে এই র্যাক মিডলওয়্যার কৌশলটি ব্যবহার করতে পারেন। এখানে Honeybadger-এ, আমরা ত্রুটিগুলি আটকাতে এবং সেগুলিকে আমাদের API এ রেকর্ড করতে এটি ব্যবহার করি। এটি করার জন্য আমরা যে কোডটি ব্যবহার করি তা এখানে:
def call(env)
config.with_request(::Rack::Request.new(env)) do
begin
env['honeybadger.config'] = config
response = @app.call(env)
rescue Exception => raised
env['honeybadger.error_id'] = notify_honeybadger(raised, env)
raise
end
framework_exception = framework_exception(env)
if framework_exception
env['honeybadger.error_id'] = notify_honeybadger(framework_exception, env)
end
response
end
ensure
Honeybadger.context.clear!
end