লেখার ত্রুটি বনাম থ্রো কখন ব্যবহার করব? বনাম সমাপ্তকরণ-অ-সমাপ্তি ত্রুটি


145

পোশকোড, http://poshcode.org/3226- তে একটি গেট-ওয়েব ফাইল স্ক্রিপ্টের দিকে তাকিয়ে আমি লক্ষ্য করেছি যে আমার কাছে এই অদ্ভুত- বিপরীত প্রতিচ্ছবি রয়েছে :

$URL_Format_Error = [string]"..."
Write-Error $URL_Format_Error
return

নীচের বিপরীতে এর কারণ কী?

$URL_Format_Error = [string]"..."
Throw $URL_Format_Error

বা আরও ভাল:

$URL_Format_Error = New-Object System.FormatException "..."
Throw $URL_Format_Error

আমি যেমন বুঝতে পেরেছি, আপনার অ-সমাপ্তি ত্রুটির জন্য লিখন-ত্রুটি ব্যবহার করা উচিত, এবং ত্রুটিগুলি বন্ধ করার জন্য থ্রো করা উচিত, সুতরাং আমার কাছে মনে হয় যে আপনি রিটার্নের পরে রাইট-ত্রুটি ব্যবহার করবেন না। পার্থক্য আছে কি?


4
আপনি কি বোঝাতে চেয়েছেন? যদি Writ_error স্ক্রিপ্টটি চালিয়ে যাওয়ার অনুমতি দেয় তবে লিখন-ত্রুটির পরে রিটার্ন স্টেটমেন্ট পাওয়া খুব বোধগম্য। ত্রুটিটি লিখিত হয়েছে এবং আপনি কোডটিতে ফিরে এসেছেন যা প্রথম স্থানে ফাংশন বলে। যেহেতু থ্রো ত্রুটিগুলি বন্ধ করার জন্য তাই এটি স্বয়ংক্রিয়ভাবে শেষ হয়ে যাবে যাতে একটি নিক্ষেপ ঘোষণায় একটি রিটার্ন বিবৃতি অকেজো
গিসি

1
@ গিসলি: এটি লক্ষ্য করা গুরুত্বপূর্ণ যে returnকোনও (উন্নত) ফাংশনের ব্লকের কলারে ফিরে আসে নাprocess ; পরিবর্তে, এটি পাইপলাইনে পরবর্তী ইনপুট অবজেক্টে এগিয়ে যায় । প্রকৃতপক্ষে, নন-টার্মিনেট ত্রুটিগুলি উত্পন্ন করার জন্য এটি সাধারণ দৃশ্য: যদি আরও ইনপুট অবজেক্টগুলি প্রক্রিয়াকরণ করা এখনও সম্ভব হয়।
mklement0

1
লক্ষ্য করুন Throwএকটি উত্পন্ন স্ক্রিপ্ট -terminating ত্রুটি, যা হিসাবে একই নয় বিবৃতি আলোড়ন সৃষ্টি ত্রুটি, উদাহরণস্বরূপ -terminating দ্বারা Get-Item -NoSuchParameterবা 1 / 0
mklement0

উত্তর:


188

Write-Errorআপনি যদি ব্যবহারকারীকে অ-সমালোচনামূলক ত্রুটি সম্পর্কে অবহিত করতে চান তবে ব্যবহার করা উচিত। ডিফল্টরূপে এটি সমস্ত কনসোলের লাল পাঠ্যে একটি ত্রুটি বার্তা মুদ্রণ করে। এটি কোনও পাইপলাইন বা লুপ চালিয়ে যাওয়া বন্ধ করে না। Throwঅন্যদিকে উত্পাদন করে যা একটি সমাপ্ত ত্রুটি বলা হয়। আপনি যদি থ্রো ব্যবহার করেন তবে পাইপলাইন এবং / অথবা বর্তমান লুপটি সমাপ্ত হবে। প্রকৃতপক্ষে আপনি কার্যকরকরণের ত্রুটিটি পরিচালনা করতে কোনও trapবা কোনও try/catchকাঠামো ব্যবহার না করে সমস্ত কার্যকরকরণের অবসান হবে ।

একটি বিষয় লক্ষণীয়, যদি আপনি সেট $ErrorActionPreferenceকরে থাকেন"Stop" এবং Write-Errorএটি ব্যবহার করেন তবে এটি একটি চূড়ান্ত ত্রুটি তৈরি করবে ।

আপনি লিখিত স্ক্রিপ্টে আমরা এটি পাই:

if ($url.Contains("http")) {
       $request = [System.Net.HttpWebRequest]::Create($url)
}
else {
       $URL_Format_Error = [string]"Connection protocol not specified. Recommended action: Try again using protocol (for example 'http://" + $url + "') instead. Function aborting..."
       Write-Error $URL_Format_Error
    return
   }

দেখে মনে হচ্ছে that ফাংশনের লেখক সেই ফাংশনটির সম্পাদন থামাতে চেয়েছিলেন এবং স্ক্রিনে একটি ত্রুটি বার্তা প্রদর্শন করতে চেয়েছিলেন তবে পুরো স্ক্রিপ্টটি কার্যকর করা বন্ধ করতে চায় নি। স্ক্রিপ্ট লেখক ব্যবহার করতে পারত throwতবে এর অর্থ try/catchহ'ল ফাংশনটি কল করার সময় আপনাকে একটি ব্যবহার করতে হবে ।

returnবর্তমান স্কোপ থেকে প্রস্থান করবে যা কোনও ফাংশন, স্ক্রিপ্ট বা স্ক্রিপ্ট ব্লক হতে পারে। এটি কোড সহ সেরা চিত্রিত:

# A foreach loop.
foreach ( $i in  (1..10) ) { Write-Host $i ; if ($i -eq 5) { return } }

# A for loop.
for ($i = 1; $i -le 10; $i++) { Write-Host $i ; if ($i -eq 5) { return } }

উভয়ের জন্য আউটপুট:

1
2
3
4
5

এখানে একটি গ্যাচা ব্যবহার returnকরছে ForEach-Object। এটি যেমন আশা করতে পারে তেমন প্রক্রিয়াজাতকরণ ভঙ্গ করবে না।

অধিক তথ্য:


ঠিক আছে, তাই থ্রো সবকিছু বন্ধ করে দেবে, লেখার ত্রুটি + রিটার্ন কেবল বর্তমান ফাংশনটি বন্ধ করে দেবে।
বিল ব্যারি

@ বিলবারি আমি একটি ব্যাখ্যা দিয়ে আমার উত্তরটি কিছুটা আপডেট করেছি return
অ্যান্ডি আরিসেম্দি

ওএস এ ফিরে ত্রুটিযুক্ত কোডটি নিশ্চিত করার জন্য প্রস্থান (1) এর পরে লিখন-ত্রুটি সম্পর্কে কী বলা যায়? এটা কি কখনও উপযুক্ত?
প্যাব্রামগুলি

19

পাওয়ার শেলের লিখন-ত্রুটি সেন্টিমলেট এবং থ্রো কীওয়ার্ডের মধ্যে প্রধান পার্থক্যটি হ'ল প্রাক্তনটি কেবল স্ট্যান্ডার্ড ত্রুটি প্রবাহে (স্ট্ডার) কিছু পাঠ্য মুদ্রণ করে , যখন পরবর্তীটি আসলে চলমান কমান্ড বা ফাংশনটির প্রসেসিং বন্ধ করে দেয় যা পরে পরিচালিত হয় which কনসোলটিতে ত্রুটি সম্পর্কে তথ্য প্রেরণ করে পাওয়ারশেল দ্বারা।

আপনার দেওয়া উদাহরণগুলিতে আপনি দুজনের ভিন্ন আচরণ পর্যবেক্ষণ করতে পারেন:

$URL_Format_Error = [string]"..."
Write-Error $URL_Format_Error
return

এই উদাহরণে ত্রুটি বার্তাটি কনসোলে প্রেরণের পরে স্পষ্টভাবে স্ক্রিপ্টটির সম্পাদন বন্ধ returnকরার জন্য কীওয়ার্ডটি যুক্ত করা হয়েছে । দ্বিতীয় উদাহরণে, অন্যদিকে, কীওয়ার্ডটি প্রয়োজনীয় নয় যেহেতু সমাপ্তি স্পষ্টভাবে দ্বারা সম্পন্ন করা হয়েছে :returnthrow

$URL_Format_Error = New-Object System.FormatException "..."
Throw $URL_Format_Error

2
আপনার যদি $ ErrorActionPreferences = "থামান" থাকে তবে লিখন-ত্রুটি প্রক্রিয়াটিও শেষ করে দেবে।
মাইকেল ফ্রেইজিম

4
ভাল তথ্য, কিন্তু PowerShell এর ত্রুটি স্ট্রিমটি অনুরূপ করতে পাঠ্য-ভিত্তিক অন্যান্য শাঁস মধ্যে দ্বারা stderr স্ট্রিম, সব PowerShell স্ট্রীম করে মত এটা রয়েছে বস্তু , যথা [System.Management.Automation.ErrorRecord]দৃষ্টান্ত, যা ডিফল্টভাবে স্বয়ংক্রিয় সংগ্রহ দ্বারা হয় $Errorসংগ্রহ ( $Error[0]সাম্প্রতিকতম ত্রুটি রয়েছে)। এমনকি যদি আপনি কেবল Write-Errorএকটি স্ট্রিং ব্যবহার করেন তবে সেই স্ট্রিংটি একটি [System.Management.Automation.ErrorRecord]দৃষ্টান্তে আবৃত হয়ে যায় ।
mklement0

16

গুরুত্বপূর্ণ : 2 টি সমাপ্তি ত্রুটি রয়েছে , যা বর্তমানের সাহায্যের বিষয়গুলি দুর্ভাগ্যক্রমে সংঘবদ্ধ :

  • বিবৃতি- সংশোধন ত্রুটিগুলি, যেমন কিছু অ-পুনরুদ্ধারযোগ্য পরিস্থিতিতে সেমিডলেট দ্বারা এবং যেভাবে একটি .NET ব্যতিক্রম / পিএস রানটাইম ত্রুটি ঘটে তার দ্বারা প্রকাশিত হিসাবে রিপোর্ট করা হয়েছে; কেবলমাত্র বিবৃতিটি সমাপ্ত করা হয় এবং স্ক্রিপ্ট প্রয়োগটি ডিফল্টরূপে চলতে থাকে

  • স্ক্রিপ্ট- সংশোধন ত্রুটিগুলি (আরও সঠিকভাবে: রানস্পেস-টার্মিনেশন )Throwত্রুটি-ক্রিয়া পছন্দ-পরিবর্তনশীল / পরামিতি মানের মাধ্যমে অন্য কোনও ত্রুটি প্রকারেরদ্বারাবা ত্রুটিযুক্ত হিসাবে ট্রিগার করা হয়েছেStop
    ধরা না পড়লে তারা বর্তমান রানস্পেস (থ্রেড) সমাপ্ত করে; এটি হ'ল, তারা কেবলমাত্র বর্তমান স্ক্রিপ্টটিই নয়, প্রযোজ্য হলে এর সমস্ত কলারও শেষ করে)।

পাওয়ারশেলের ত্রুটি পরিচালনার একটি বিস্তৃত ওভারভিউয়ের জন্য, এই গিটহাব ডকুমেন্টেশন ইস্যুটি দেখুন

এই পোস্টের বাকী অংশগুলি অ-টার্মিনেটিং বনাম স্টেটমেন্ট-টার্মিনেটিং ত্রুটিতে ফোকাস করে ।


প্রশ্নের মূল বিষয়টিকে কেন্দ্র করে বিদ্যমান সহায়ক উত্তরের পরিপূরক: আপনি কীভাবে চয়ন করবেন যে কোনও বিবৃতি- সমাপ্তি বা অবসানহীন ত্রুটিটি রিপোর্ট করা উচিত ?

সিএমডলেট ত্রুটি প্রতিবেদনে সহায়ক নির্দেশিকা রয়েছে; আমাকে একটি ব্যবহারিক সংক্ষিপ্তসার চেষ্টা করুন :

পিছনে সাধারণ ধারণা অ সসীম ত্রুটি অনুমতি দিতে "ত্রুটি-সহিষ্ণু" বৃহৎ ইনপুট সেট প্রক্রিয়াকরণ করা হয় একটি প্রক্রিয়া করতে ব্যর্থ হয়েছে: উপসেট প্রক্রিয়া - ইনপুট বস্তুর করা উচিত নয় (ডিফল্ট অনুসারে) পরিত্যাগ - সম্ভাব্য দীর্ঘক্ষন ধরে চলা সামগ্রিকভাবে , স্বয়ংক্রিয় ভেরিয়েবলে সংগৃহীত ত্রুটি রেকর্ডের মাধ্যমে রিপোর্ট করা - আপনাকে ত্রুটিগুলি পরিদর্শন করতে এবং কেবলমাত্র ব্যর্থ বস্তুগুলিকে পুনরায় প্রসেসের অনুমতি দেয় $Error

  • যদি আপনার সেমিডলেট / অ্যাডভান্সড ফাংশন থাকে তবে একটি নন-টার্মিনেটিং ত্রুটির প্রতিবেদন করুন :

    • একাধিক ইনপুট বস্তু গ্রহণ করে পাইপলাইন ইনপুট এবং / অথবা অ্যারে-মূল্যবান পরামিতি মাধ্যমে, এবং
    • স্পেসিফিক ইনপুট অবজেক্টস এবং এর জন্য ত্রুটিগুলি ঘটে
    • এই ত্রুটিগুলি মূল ইনপুট অবজেক্টগুলির প্রসেসিং আটকাবে না ( পরিস্থিতিগতভাবে , কোনও ইনপুট অবজেক্ট থাকতে পারে না এবং / বা পূর্ববর্তী ইনপুট অবজেক্টগুলি ইতিমধ্যে সফলভাবে প্রক্রিয়া করা হতে পারে)।
      • উন্নত ফাংশন ইন, ব্যবহার $PSCmdlet.WriteError()একটি অ-সসীম ত্রুটি প্রতিবেদন করার জন্য ( Write-Error, দুর্ভাগ্যবশত, কারণ হবে না $?নির্ধারণ করা $Falseমধ্যে আহ্বানকারী এর সুযোগ - দেখুন এই GitHub ইস্যু )।
      • পরিচালনা একটি অ-সসীম ত্রুটি: $?আপনি বলে কিনা সাম্প্রতিকতম কমান্ড রিপোর্ট অন্তত একটি অ সসীম ত্রুটি।
        • সুতরাং, $?হ'ল এটির$False অর্থ হ'ল ইনপুট অবজেক্টগুলির যে কোনও (অযৌক্তিক) উপসেটটি সঠিকভাবে প্রক্রিয়াজাত হয়নি, সম্ভবত পুরো সেটটি।
        • পছন্দ পরিবর্তনশীল $ErrorActionPreferenceএবং / অথবা সাধারণ সেমিডলেট প্যারামিটার -ErrorActionত্রুটি আউটপুট আচরণের ক্ষেত্রে এবং কেবলমাত্র নন-টার্মিনেটিং ত্রুটিগুলি স্ক্রিপ্ট-নির্ধারণকারীগুলির মধ্যে বাড়ানো উচিত কিনা তা অবৈধ -ত্রুটিযুক্ত ত্রুটির আচরণকে (কেবলমাত্র) পরিবর্তন করতে পারে ।
  • অন্যান্য সমস্ত ক্ষেত্রে একটি STATEMENT-TERMINATING ত্রুটির প্রতিবেদন করুন ।

    • উল্লেখযোগ্যভাবে, যদি কোনও সেমিডলেট / অ্যাডভান্সড ফাংশনে একটি ত্রুটি দেখা দেয় যা কেবল একটি সিঙ্গল বা কোনও ইনপুট অবজেক্ট গ্রহণ করে এবং কোনও বা একটি সিঙ্গেল আউটপুট বস্তু আউটপুট দেয় বা কেবলমাত্র প্যারামিটার ইনপুট নেয় এবং প্রদত্ত প্যারামিটার মানগুলি অর্থবোধক ক্রিয়াকে রোধ করে।
      • উন্নত ফাংশনগুলিতে, আপনাকে $PSCmdlet.ThrowTerminatingError()স্টেটমেন্ট-টার্মিনেটিং ত্রুটি তৈরি করতে অবশ্যই ব্যবহার করতে হবে ।
      • দ্রষ্টব্য, বিপরীতে, Throwকীওয়ার্ডটি একটি স্ক্রিপ্ট- নির্ধারণ ত্রুটি তৈরি করে যা পুরো স্ক্রিপ্টটি বাতিল করে (প্রযুক্তিগতভাবে: বর্তমান থ্রেড )।
      • পরিচালনা একটি বিবৃতি-সসীম ত্রুটি: একটি try/catchহ্যান্ডলার বা trapবিবৃতি ব্যবহার করা যেতে পারে (যা করতে পারবেন সঙ্গে ব্যবহার করা অ সসীম ত্রুটি), কিন্তু নোট এমনকি যে বিবৃতি ডিফল্টরূপে -terminating ত্রুটি চালু করা থেকে স্ক্রিপ্ট বাকি বাধাদান করো না। সঙ্গে অ সসীম ত্রুটি, $?প্রতিফলিত $Falseযদি পূর্ববর্তী বিবৃতি এক বিবৃতিতে-সসীম ত্রুটি আলোড়ন সৃষ্টি।

দুঃখের বিষয়, পাওয়ারশেলের নিজস্ব কোর সিএমডিলেটগুলির সমস্তই এই নিয়মগুলি দ্বারা খেলা হয় না :

  • New-TemporaryFileপাইপলাইন ইনপুট গ্রহণ না করে এবং শুধুমাত্র একটি আউটপুট অবজেক্ট তৈরি করা সত্ত্বেও, ব্যর্থ হওয়ার সম্ভাবনা থাকলেও (PSv5 +) নন-টার্মিনেটিং ত্রুটির প্রতিবেদন করবে - এটি কমপক্ষে পাওয়ারশেল [কোর] .0.০ হিসাবে সংশোধন করা হয়েছে, তবে এই গিটহাবটি দেখুন ইস্যু

  • Resume-Jobসহায়তার দাবী যে একটি অসমর্থিত চাকরির ধরণের (যেমন একটি কাজের সাথে তৈরি করা Start-Job, যা সমর্থিত নয়, কারণ Resume-Jobকেবল ওয়ার্কফ্লো কাজের ক্ষেত্রে প্রযোজ্য ) পাস করার ফলে একটি চূড়ান্ত ত্রুটি হয়, তবে PSV5.1 হিসাবে এটি সত্য নয়।


8

Write-Errorফাংশনের গ্রাহককে -ErrorAction SilentlyContinue(বিকল্পভাবে -ea 0) এর মাধ্যমে ত্রুটি বার্তাটি দমন করতে দেয় । যখন throwপ্রয়োজন একটিtry{...} catch {..}

একটি চেষ্টা ব্যবহার করতে ... সাথে ধরা Write-Error:

try {
    SomeFunction -ErrorAction Stop
}
catch {
    DoSomething
}

আপনি যদি ত্রুটি বার্তাটি দমন করতে চান তবে কেন আপনাকে লিখন-ত্রুটিটি একেবারে কল করতে হবে?
মাইকেল ফ্রেইজিম

8

ছাড়াও অ্যান্ডি Arismendi এর উত্তর :

লিখন-ত্রুটি প্রক্রিয়াটি সমাপ্ত করে কিনা সেটি $ErrorActionPreferenceসেটিংসের উপর নির্ভর করে ।

অ তুচ্ছ স্ক্রিপ্ট জন্য $ErrorActionPreference = "Stop"একটি হল প্রস্তাবিত সেটিং ফাস্ট ব্যর্থ।

"ত্রুটিগুলির প্রতি শ্রদ্ধার সাথে পাওয়ারশেলের ডিফল্ট আচরণ, যা ত্রুটি অব্যাহত রাখতে হয় ... খুব ভিবি 6 বোধ হয়" ত্রুটি পুনরায় শুরু করার পরে "- ইশ"

( http://codebetter.com/jameskovacs/2010/02/25/the-exec-problem/ থেকে )

যাইহোক, এটি Write-Errorকলগুলি বন্ধ করে দেয়।

ব্যবহার করার জন্য লেখা-ত্রুটি অন্যান্য পরিবেশ সেটিংস নির্বিশেষে একটি অ-সসীম কমান্ড হিসাবে, আপনি ব্যবহার করতে পারেন সাধারণ পরামিতি -ErrorAction মান Continue:

 Write-Error "Error Message" -ErrorAction:Continue

0

কোডটি যদি আপনার পড়া সঠিক হয় তবে আপনি সঠিক। ত্রুটিগুলি শোধ করার জন্য ব্যবহার করা উচিত throwএবং যদি আপনি .NET ধরণের সাথে কাজ করে থাকেন তবে। নেট ব্যতিক্রমী কনভেনশনগুলি অনুসরণ করাও সহায়ক।

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