মডিউল পাঠ (2/5)
ইডিওম্যাটিক ত্রুটি হ্যান্ডলিং
Go-তে ত্রুটি পরিচালনা করা সুস্পষ্ট: কোনো ব্যতিক্রম নেই, কোনো চেষ্টা/ক্যাচ নেই। ব্যর্থ হতে পারে এমন প্রতিটি ফাংশন error এর শেষ মান হিসাবে ফেরত দেয়, এবং কলকারী সিদ্ধান্ত নেয়। এই অধ্যায়টি একটি শক্তিশালী উপায়ে ত্রুটিগুলি উত্পাদন, প্রচার এবং পরিদর্শন করার জন্য বাহাদুরি নিদর্শনগুলি সংগ্রহ করে৷
সুবর্ণ নিয়ম
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("config %s: %w", path, err)
}চারটি মূলনীতি:
errorহল শেষ রিটার্ন।if err != nilএর সাথে অবিলম্বে চেক করুন।- প্রসঙ্গ যোগ করুন প্রচার করার আগে (
fmt.Errorf+%wসহ)। - কখনও উপেক্ষা করবেন না একটি ত্রুটি: হয় এটি পরিচালনা করুন, লগ করুন বা ফেরত দিন।
_ = file.Close() // EXPLICITLY ignored (you know what you're doing)সেন্টিনেল ত্রুটি
একটি সেন্টিনেল ত্রুটি হল একটি এক্সপোর্ট করা গ্লোবাল ভেরিয়েবল var ErrXxx = errors.New("...") যার সাথে কলকারী তুলনা করতে পারে:
package store
var ErrNotFound = errors.New("not found")
func Get(key string) (string, error) {
if !exists(key) {
return "", ErrNotFound
}
// ...
}কলার ব্যবহার করে errors.Is (NOT ==), যেটি মোড়ানো চেন দিয়ে চলে:
v, err := store.Get(k)
if errors.Is(err, store.ErrNotFound) {
// handle 404
}আদর্শ উদাহরণ: io.EOF, sql.ErrNoRows, os.ErrNotExist।
কাস্টম টাইপ করা ত্রুটি
কাঠামোগত ডেটা বহন করতে (HTTP কোড, অবৈধ ক্ষেত্র, ইত্যাদি), একটি প্রকার সংজ্ঞায়িত করুন:
type ValidationError struct {
Field string
Msg string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Msg)
}কলার errors.As ব্যবহার করে শৃঙ্খল বরাবর নিরাপদে নিম্নমুখী হতে:
var ve *ValidationError
if errors.As(err, &ve) {
fmt.Println("invalid field:", ve.Field)
}errors.As Unwrap() শৃঙ্খলে চলে যতক্ষণ না এটি পাস করা পয়েন্টারে অ্যাসাইনযোগ্য একটি ত্রুটি খুঁজে পায়৷
%w দিয়ে মোড়ানো
fmt.Errorf %w ক্রিয়াপদের সাথে একটি ত্রুটি তৈরি করে যা আসলটিকে রেপ করে, এটিকে errors.Is/errors.As এর জন্য সংরক্ষণ করে:
if err := db.Query(); err != nil {
return fmt.Errorf("load users: %w", err)
}%w (%v বা %s ব্যবহার করে) ছাড়া আপনি একটি সমৃদ্ধ স্ট্রিং পাবেন কিন্তু **চেইনটি ** হারান**: কলার আর নির্দিষ্ট ত্রুটি সনাক্ত করতে পারবেন না।
%w এর জন্য নিয়ম:
- প্রতি
fmt.Errorfকলে শুধুমাত্র একটি (মাল্টি-র্যাপ প্রয়োজনerrors.Join)। - আর্গুমেন্টটি অবশ্যই একটি
errorহতে হবে, একটি স্ট্রিং নয়৷ - প্রসঙ্গ যোগ করুন, আসল বার্তার নকল করবেন না।
// bad: duplicates
return fmt.Errorf("error: %w", err) // "error: file not found"
// good: useful context
return fmt.Errorf("load config %s: %w", path, err)একাধিক ত্রুটির জন্য errors.Join
Go 1.20 থেকে, errors.Join(errs...) একাধিক ত্রুটিকে একত্রিত করে যা সেগুলিকে errors.Is/As দ্বারা সনাক্তযোগ্য রাখে:
var errs []error
for _, item := range items {
if err := process(item); err != nil {
errs = append(errs, fmt.Errorf("item %s: %w", item.ID, err))
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}কখন ব্যবহার করবেন panic
প্রত্যাশিত ত্রুটির জন্য কখনই নয়। শুধু তিনটি ক্ষেত্রে:
- অপুনরুদ্ধারযোগ্য বাগ: একটি পরিবর্তনকারী এমন একটি স্থানে লঙ্ঘন করেছে যা "ঘটতে পারে না" (
panic("unreachable"))। - একটি স্বতন্ত্র প্রোগ্রামের
init()/main()-এ ব্যর্থ প্রাথমিককরণ (গুরুত্বপূর্ণ কনফিগারেশন অনুপস্থিত → দ্রুত ব্যর্থ)। - লাইব্রেরি API যা স্পষ্টভাবে এটিকে নথিভুক্ত করে: যেমন,
regexp.MustCompile(প্যাটার্নটি অবৈধ হলে প্যানিক — গ্রহণযোগ্য কারণ প্যাটার্নটি একটি বিল্ড-টাইম ধ্রুবক)।
বাকি সব error। **প্রচার করতে ** শর্টকাট হিসেবে panic ব্যবহার করবেন না: এটি রচনাকে ভেঙে দেয়, defer Close() এড়িয়ে যায় এবং কলকারীকে অভিভূত করে।
ব্যায়াম
Wrappa l'error di os.ReadFile con fmt.Errorf usando il verbo %w e aggiungendo il contesto 'config:' (con il path)।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
USA errors.Is per verificare se err nella catena di wrap corrisponde alla sentinella ErrNotFound e stampa 'manca!' তাল ক্ষেত্রে
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
কোন লাইব্রেরিয়ায় আতঙ্ক ব্যবহার করতে চান?
func F(x int) {
// ??? panic(...)
}