PL / pgSQL এ ম্যানুয়ালি উত্থাপিত ব্যতিক্রমের জন্য কীভাবে ব্যতিক্রম প্রসঙ্গ পাবেন?


11

পোস্টগ্রিসে আমরা এই কোডটি ব্যবহার করে ব্যতিক্রমগুলির "স্ট্যাক ট্রেস" পাই:

EXCEPTION WHEN others THEN
    GET STACKED DIAGNOSTICS v_error_stack = PG_EXCEPTION_CONTEXT;

এটি "প্রাকৃতিক" ব্যতিক্রমগুলির জন্য সূক্ষ্মভাবে কাজ করে, তবে যদি আমরা ব্যবহার করে একটি ব্যতিক্রম উত্থাপন করি

RAISE EXCEPTION 'This is an error!';

... তাহলে কোনও স্ট্যাক ট্রেস নেই is একটি মেলিং তালিকার এন্ট্রি অনুসারে , এটি ইচ্ছাকৃত হতে পারে, যদিও আমি আমার জীবনের জন্য তা বুঝতে পারি না। এটি আমাকে ব্যবহার ব্যতীত কোনও ব্যতিক্রম ছুঁড়ে ফেলার অন্য কোনও উপায় বের করতে চায় RAISE। আমি কি স্পষ্ট কিছু মিস করছি? কারও কি এর জন্য কৌশল আছে? Postgres এ ছুঁড়ে ফেলতে আমি কীভাবে ব্যতিক্রম পাব যাতে আমার পছন্দের একটি স্ট্রিং থাকে, যাতে আমি ত্রুটি বার্তায় আমার স্ট্রিংটিই পাই না, তবে পুরো স্ট্যাক ট্রেসটিও পাই?

এখানে একটি সম্পূর্ণ উদাহরণ:

CREATE OR REPLACE FUNCTION error_test() RETURNS json AS $$
DECLARE
    v_error_stack text;
BEGIN

    -- Comment this out to see how a "normal" exception will give you the stack trace
    RAISE EXCEPTION 'This exception will not get a stack trace';

    -- This will give a divide by zero error, complete with stack trace
    SELECT 1/0;

-- In case of any exception, wrap it in error object and send it back as json
EXCEPTION WHEN others THEN

    -- If the exception we're catching is one that Postgres threw,
    -- like a divide by zero error, then this will get the full
    -- stack trace of the place where the exception was thrown.
    -- However, since we are catching an exception we raised manually
    -- using RAISE EXCEPTION, there is no context/stack trace!
    GET STACKED DIAGNOSTICS v_error_stack = PG_EXCEPTION_CONTEXT;

    RAISE WARNING 'The stack trace of the error is: "%"', v_error_stack;

    return to_json(v_error_stack);
END;
$$ LANGUAGE plpgsql;

এখানে একটি সাধারণ উদাহরণ দেখানো ভাল ধারণা হতে পারে।
ক্রেগ রিঞ্জার

ভাল পয়েন্ট @ ক্রেইগ্রিঞ্জার। সম্পন্ন!
তিত্তে

এটি স্বয়ংসম্পূর্ণ নয়। কি error_info? দেখতে কাস্টম টাইপের মতো।
ক্রেগ রিঞ্জার

দুঃখিত - ভেবেছিলেন আপনি কেবল সাধারণ প্রসঙ্গ চেয়েছিলেন। আমি বহির্মুখী জিনিসগুলি সরিয়ে ফেলেছি।
তিত্তে

উত্তর:


9

এই আচরণটি ডিজাইনের দ্বারা প্রদর্শিত হয়।

ইন src/pl/plpgsql/src/pl_exec.cত্রুটি প্রসঙ্গ কলব্যাক স্পষ্টভাবে চেক দেখতে যদি এটি একটি পিএল / PgSQL প্রেক্ষাপটে বলা হচ্ছে হচ্ছে RAISEবিবৃতি এবং, যদি তাই হয়, ত্রুটি প্রসঙ্গ emitting ছেড়ে যাওয়া:

/*
 * error context callback to let us supply a call-stack traceback
 */
static void
plpgsql_exec_error_callback(void *arg)
{
        PLpgSQL_execstate *estate = (PLpgSQL_execstate *) arg;

        /* if we are doing RAISE, don't report its location */
        if (estate->err_text == raise_skip_msg)
                return;

কেন ক্ষেত্রে তা সুনির্দিষ্ট কোনও রেফারেন্স আমি পাই না ।

অভ্যন্তরীণভাবে সার্ভারে, প্রসঙ্গের স্ট্যাকটি প্রসেসিংয়ের মাধ্যমে উত্পন্ন হয় error_context_stack, এটি একটি শৃঙ্খলযুক্ত কলব্যাক যা কল করার সময় তালিকায় তথ্য সংযোজন করে।

যখন পিএল / পিজিএসকিউএল কোনও ফাংশনে প্রবেশ করে তখন এটি ত্রুটি প্রসঙ্গে ক্যালব্যাক স্ট্যাকের সাথে একটি আইটেম যুক্ত করে। যখন এটি কোনও ফাংশন ছেড়ে যায় তখন এটি স্ট্যাক থেকে কোনও আইটেম সরিয়ে দেয়।

পোস্টগ্র্রেএসকিউএল সার্ভারের ত্রুটি প্রতিবেদনের ফাংশনগুলি যদি পছন্দ করে ereportবা elogবলা হয় তবে এটি ত্রুটি প্রসঙ্গে কলব্যাককে কল করে। কিন্তু পিএল / পিজিএসকিউএলে যদি এটি লক্ষ্য করে যে RAISEএটির কলব্যাকগুলি ইচ্ছাকৃতভাবে কিছুই করছে না called

এটি দেওয়া, পোস্টগ্র্রেএসকিউএল প্যাচ না করে আপনি যা চান তা অর্জনের কোনও উপায় আমি দেখতে পাচ্ছি না। আমি পিএএসএসকিএল-জেনারেলকে মেইল ​​পোস্ট করার পরামর্শ দিচ্ছি কেন RAISEএখনই ত্রুটি প্রসঙ্গটি সরবরাহ করে না যে পিএল / পিজিকিউএল এটির GET STACKED DIAGNOSTICSব্যবহার করতে হবে।

(বিটিডাব্লু, ব্যতিক্রম প্রসঙ্গটি স্ট্যাক ট্রেস হিসাবে তেমন কিছু নয় It এটি দেখতে অনেকটা একরকম লাগে কারণ পিএল / পিজিএসকিউএল স্ট্যাকটিতে প্রতিটি ফাংশন কল যুক্ত করে, তবে এটি সার্ভারের অন্যান্য বিবরণের জন্যও ব্যবহৃত হয়))


দ্রুত এবং পুঙ্খানুপুঙ্খ উত্তরের জন্য আপনাকে অনেক ধন্যবাদ। এটি আমার কাছে অদ্ভুত বলে মনে হচ্ছে এবং অবশ্যই আমার প্রত্যাশার বিরুদ্ধে। RAISEসেই চেক দ্বারা কার্যকারিতা হ্রাস পাচ্ছে। আমি তাদের লিখতে হবে।
তিত্তে

@ টেটে দয়া করে আপনার প্রশ্নের একটি লিঙ্ক এখানে অন্তর্ভুক্ত করুন তবে নিশ্চিত করুন যে আপনার মেলটি সম্পূর্ণ এবং লিঙ্কটি অনুসরণ না করেই বোঝা যায় ; কেবলমাত্র লিঙ্ক-বা লিঙ্ক-বেশিরভাগ পোস্টকে উপেক্ষা করে অনেকে। আপনি যদি আর্কাইভ.পোস্টগ্রেসক্লোল.আর.গোর মাধ্যমে এখানে মন্তব্যগুলিতে আপনার পোস্টে একটি লিঙ্ক পপ করার সুযোগ পান যা পরে অন্য ব্যক্তিকে সাহায্য করার জন্য সত্যই দুর্দান্ত esome
ক্রেগ রিঞ্জার

ধন্যবাদ ক্রেগ সদুপদেশ. আমি এখানে একটি থ্রেড তৈরি করেছি: postgresql.org/message-id/… এখনকার হিসাবে, তারা ইস্যুটির একটি ভাল সমাধান খুঁজছেন।
তিত্তে

6

আপনি এই বিধিনিষেধের আশেপাশে কাজ করতে পারেন এবং আপনার জন্য ত্রুটিটি উত্থাপনকারী (সতর্কতা, বিজ্ঞপ্তি, ...) কল করে পিএলপিএইচএসএল ইমিট ত্রুটি প্রসঙ্গটি পছন্দসই হিসাবে তৈরি করতে পারেন।

কয়েক বছর আগে আমি এর জন্য একটি সমাধান পোস্ট করেছি - আমার প্রথম পোস্টের একটিতে ডিবিএএসইতে :

-- helper function to raise an exception with CONTEXT
CREATE OR REPLACE FUNCTION f_raise(_lvl text = 'EXCEPTION'
                                  ,_msg text = 'Default error msg.')
  RETURNS void AS
$func$
BEGIN
   CASE upper(_lvl)
      WHEN 'EXCEPTION' THEN RAISE EXCEPTION '%', _msg;
      WHEN 'WARNING'   THEN RAISE WARNING   '%', _msg;
      WHEN 'NOTICE'    THEN RAISE NOTICE    '%', _msg;
      WHEN 'DEBUG'     THEN RAISE DEBUG     '%', _msg;
      WHEN 'LOG'       THEN RAISE LOG       '%', _msg;
      WHEN 'INFO'      THEN RAISE INFO      '%', _msg;
      ELSE RAISE EXCEPTION 'f_raise(): unexpected raise-level: "%"', _lvl;
   END CASE;
END
$func$  LANGUAGE plpgsql STRICT;

বিবরণ:

আমি আপনার পোস্ট পরীক্ষার কেসটি প্রগ্রেড করে দেখিয়েছি এটি পোস্টগ্রিস 9.3 এ কাজ করে:

এসকিউএল ফিডল।


আপনাকে অনেক ধন্যবাদ! মজাদারভাবে যথেষ্ট, পোস্ট করার আগে আমি আসলে আপনার সমাধান নিয়ে পরীক্ষা-নিরীক্ষা করেছি, তবে অবশ্যই আমি কিছু ভুল করেছি এবং আমার প্রত্যাশা প্রসঙ্গটি আমি পাইনি। এখন যেহেতু আমি ঝাঁকুনিটি দেখেছি (আমাকেও তা দেখানোর জন্য ধন্যবাদ), আমি এটিকে আরও একটি শট দেব!
তিত্তে

সুন্দরভাবে সম্পন্ন; এটি প্রয়োজনীয় হওয়া উচিত নয়, তবে দেখে মনে হচ্ছে এটি কৌশলটি করবে।
ক্রেগ রিঞ্জার

@ ক্রেইগ্রিঞ্জার: যেহেতু ব্যতিক্রমগুলি হওয়া উচিত, ভাল, ব্যতিক্রম , ন্যূনতম পারফরম্যান্স এফেক্টটি বিবেচনা করা উচিত নয় either আমাদের কাছে এইভাবে সমস্ত বিকল্প রয়েছে।
এরউইন ব্র্যান্ডসটেটার

সম্পূর্ণরূপে সম্মত হোন, আমি ঠিক দেখতে চাই যে কোনও সময়ে কর্মক্ষেত্রের প্রয়োজনীয়তা চলে যায়।
ক্রেগ রিঞ্জার

@ ক্রেইগ্রিঞ্জার: সত্য। যদি তা খুব শীঘ্রই কোনও সময়ে ঘটতে না পারে, আমরা ম্যানুয়ালটিতে এই পরামর্শটি প্রস্তাব করতে পারি ...
এরউইন ব্র্যান্ডসটেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.