Error Handling in Go (এরর হ্যান্ডলিং)
Go প্রোগ্রামিং ভাষায় Error Handling একটি গুরুত্বপূর্ণ বিষয়, কারণ Go-তে কোনো exceptions নেই, তবে error values ব্যবহার করা হয়। এর মানে হচ্ছে যে, Go কোডে যদি কোনো ত্রুটি (error) ঘটে, তাহলে ফাংশন একটি error টাইপ রিটার্ন করে, যা পরে ম্যানেজ করা হয়। Go এর এরর হ্যান্ডলিং খুবই সরল এবং স্পষ্টভাবে পরিচালনা করা হয়।
১. Error Types in Go (এরর টাইপ)
Go-তে error টাইপ একটি বিল্ট-ইন ইন্টারফেস যা সাধারণত ফাংশন থেকে রিটার্ন করা হয়। error টাইপটি সাধারণত একটি স্ট্রিং ধারণ করে যা ত্রুটির বিবরণ দেয়।
১.১ Error Interface
package main
import "fmt"
// Error টাইপ ডিফাইন করা
type MyError struct {
Code int
Message string
}
// Error মেথড ডিফাইন করা
func (e MyError) Error() string {
return fmt.Sprintf("Error %d: %s", e.Code, e.Message)
}
func main() {
// Custom error তৈরি করা
err := MyError{
Code: 404,
Message: "Page not found",
}
fmt.Println(err.Error()) // আউটপুট: Error 404: Page not found
}এখানে, MyError নামক একটি কাস্টম টাইপ তৈরি করা হয়েছে এবং তার মধ্যে Error() মেথড ডিফাইন করা হয়েছে, যা error ইন্টারফেসের মেথড। এটি কাস্টম এরর মেসেজ প্রিন্ট করতে ব্যবহৃত হয়।
২. Error Handling Using Return Values (ফাংশন থেকে error রিটার্ন করা)
Go-তে এরর হ্যান্ডলিং সাধারণত return values এর মাধ্যমে করা হয়। একটি ফাংশন যদি কোনো ত্রুটি ঘটায়, তবে এটি একটি error টাইপ রিটার্ন করে। এরপর আপনি ফাংশন কলের পরে সেই error চেক করতে পারেন।
২.১ Error Handling Example
package main
import (
"fmt"
"errors"
)
// ফাংশন যা error রিটার্ন করে
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero is not allowed") // error তৈরি করা
}
return a / b, nil // error নেই, তাই nil রিটার্ন
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: division by zero is not allowed
} else {
fmt.Println("Result:", result)
}
}এখানে, divide ফাংশন দুটি মান নেবে এবং যদি দ্বিতীয় মান (b) শূন্য হয়, তাহলে একটি error রিটার্ন করবে। আমরা err চেক করে যদি কোনো ত্রুটি ঘটে, তবে ত্রুটির মেসেজ প্রিন্ট করি।
আউটপুট:
Error: division by zero is not allowed৩. Nil Error Handling
যখন কোনো error না ঘটে, তখন Go-তে error ভ্যালু nil হয়ে থাকে, এবং আমরা এই ভ্যালু চেক করে error এর উপস্থিতি নির্ধারণ করতে পারি।
৩.১ Nil Error Example
package main
import (
"fmt"
"errors"
)
// ফাংশন যা error রিটার্ন করে
func getUserAge(user string) (int, error) {
if user == "John" {
return 30, nil // no error
}
return 0, errors.New("user not found") // error তৈরি করা
}
func main() {
age, err := getUserAge("John")
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Age:", age)
}
age, err = getUserAge("Alice")
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: user not found
} else {
fmt.Println("Age:", age)
}
}এখানে, getUserAge ফাংশনটি যদি ব্যবহারকারীর নাম "John" থাকে তবে একটি বয়স ফেরত দেয় এবং কোনো error রিটার্ন করে না, অন্যথায় একটি error রিটার্ন করে।
আউটপুট:
Age: 30
Error: user not found৪. Custom Errors (কাস্টম এরর তৈরি করা)
Go-তে আপনি কাস্টম error তৈরি করতে পারেন একটি নতুন টাইপ ডিফাইন করে এবং এর মধ্যে Error() মেথড বাস্তবায়ন করে।
৪.১ Custom Error Example
package main
import "fmt"
// Custom error টাইপ ডিফাইন করা
type MyCustomError struct {
Code int
Message string
}
// Error মেথড বাস্তবায়ন
func (e MyCustomError) Error() string {
return fmt.Sprintf("Custom Error %d: %s", e.Code, e.Message)
}
func checkAge(age int) error {
if age < 18 {
return MyCustomError{Code: 101, Message: "Age is less than 18"}
}
return nil
}
func main() {
err := checkAge(16)
if err != nil {
fmt.Println(err) // আউটপুট: Custom Error 101: Age is less than 18
}
}এখানে, MyCustomError একটি কাস্টম error টাইপ, এবং Error() মেথড এর মাধ্যমে এরর মেসেজ প্রিন্ট করা হয়।
৫. Panic and Recover (প্যানিক এবং রিকভার)
Go তে panic এবং recover ব্যবহার করে আপনি গুরুতর ত্রুটি (error) অবস্থায় প্রোগ্রামকে থামানো এবং পুনরুদ্ধার করতে পারেন। panic একটি ফাংশনে ডাকা হয় যখন একটি সমস্যা গুরুতর হয়ে ওঠে এবং recover ব্যবহার করা হয় সেই সমস্যা থেকে প্রোগ্রামকে পুনরুদ্ধার করার জন্য।
৫.১ Panic and Recover Example
package main
import "fmt"
func riskyFunction() {
panic("Something went wrong!")
}
func main() {
// defer এবং recover ব্যবহার করা
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from:", r) // আউটপুট: Recovered from: Something went wrong!
}
}()
riskyFunction()
fmt.Println("This line will not be executed.")
}এখানে, riskyFunction ফাংশনে panic ঘটানো হয়েছে। পরে, defer ব্লকে recover ব্যবহার করে আমরা সেই panic থেকে প্রোগ্রামকে পুনরুদ্ধার করেছি।
আউটপুট:
Recovered from: Something went wrong!৬. Error Handling Best Practices (এরর হ্যান্ডলিং এর সেরা অনুশীলন)
- Error চেক করা: Go-তে প্রতিটি ফাংশন কলের পর error চেক করা উচিত। এটি নিশ্চিত করে যে ফাংশনটি সফলভাবে চলেছে।
- Clear Error Messages: আপনার error মেসেজগুলো স্পষ্ট ও বোধগম্য হওয়া উচিত যাতে ডেভেলপাররা সহজে সমস্যা চিহ্নিত করতে পারে।
- Custom Errors: আপনি যদি নির্দিষ্ট ত্রুটির জন্য কাস্টম error টাইপ তৈরি করতে চান, তবে তা স্পষ্টভাবে করার চেষ্টা করুন, যাতে সঠিক error handling করতে সুবিধা হয়।
- Avoid Panic: সাধারণত
panicব্যবহার এড়ানো উচিত, তবে আপনি গুরুতর ত্রুটির ক্ষেত্রে এটি ব্যবহার করতে পারেন।
সারসংক্ষেপ
- Error Handling: Go-তে error handling একটি গুরুত্বপূর্ণ বিষয়, যেখানে
errorটাইপ ব্যবহার করে ত্রুটির তথ্য রাখা হয় এবং সেগুলো চেক করা হয়। - Custom Errors: Go-তে কাস্টম error তৈরি করে আপনি নির্দিষ্ট ত্রুটির পরিস্থিতি স্পষ্টভাবে উল্লেখ করতে পারেন।
- Panic and Recover:
panicএবংrecoverব্যবহারের মাধ্যমে গুরুতর ত্রুটির পর প্রোগ্রাম থামানো এবং পুনরুদ্ধার করা সম্ভব। - Nil Errors: Error হ্যান্ডলিংয়ের ক্ষেত্রে
nilচেক করার মাধ্যমে নিশ্চিত হওয়া যায় যে কোনো error ঘটেছে কিনা।
Go তে error handling খুবই সরল এবং কার্যকরী, যা প্রোগ্রামগুলির নির্ভরযোগ্যতা এবং স্থিতিশীলতা নিশ্চিত করে।
Go-তে Error Handling মেকানিজম
১. Go-তে Error Handling এর ধারণা
Go প্রোগ্রামিং ভাষায় Error Handling একটি গুরুত্বপূর্ণ অংশ এবং এটি explicit (স্পষ্ট) পদ্ধতির মাধ্যমে পরিচালিত হয়। অন্যান্য ভাষার মতো Go তে exception handling ব্যবহার করা হয় না, বরং error টাইপের মাধ্যমে সমস্যা বা ত্রুটি পরিচালনা করা হয়। Go তে error handling মূলত ফাংশন রিটার্ন ভ্যালু হিসেবে error টাইপের মান ফেরত দেয়, যা ডেভেলপারদের সিদ্ধান্ত নিতে সাহায্য করে যে কোনো অপারেশন সফল হয়েছে বা ব্যর্থ হয়েছে।
১.১ Go Error Handling এর মূল বৈশিষ্ট্য
- Go তে error একটি বিল্ট-ইন ইন্টারফেস টাইপ যা একটি কাস্টম ধরনের ত্রুটির পরিস্থিতি প্রতিনিধিত্ব করতে ব্যবহৃত হয়।
- প্রতিটি ফাংশন যেখানে একটি ত্রুটি ঘটতে পারে, সেখানে error রিটার্ন ভ্যালু প্রদান করতে হবে।
- Go তে ত্রুটির মোকাবিলা করা হয় ফাংশনের রিটার্ন ভ্যালু পরীক্ষা করে।
২. Go তে Error Interface
Go তে error একটি interface যা একটি Error() মেথড ধারণ করে:
type error interface {
Error() string
}এখানে, Error() মেথডটি একটি স্ট্রিং ফেরত দেয় যা ত্রুটির বার্তা ধারণ করে।
৩. Error Handling এর মৌলিক ধারণা
৩.১ Error রিটার্ন করা
Go তে যখন একটি ত্রুটি ঘটে, তখন একটি ফাংশন error টাইপের রিটার্ন মান ফেরত দেয়। উদাহরণস্বরূপ:
package main
import "fmt"
import "errors"
// একটি ফাংশন যা error রিটার্ন করবে
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: cannot divide by zero
} else {
fmt.Println("Result:", result)
}
}এখানে, divide ফাংশনটি যদি b এর মান 0 হয়, তবে এটি একটি error রিটার্ন করবে। main ফাংশনে, আমরা err এর মান পরীক্ষা করি, এবং যদি এটি nil না হয়, তবে ত্রুটি বার্তা প্রিন্ট করা হয়।
আউটপুট:
Error: cannot divide by zero৩.২ Go-তে Error তৈরি করা
Go তে errors.New() ফাংশন দিয়ে একটি নতুন error তৈরি করা যায়। এটি একটি স্ট্রিং আর্গুমেন্ট নেয় এবং তা দিয়ে একটি error অবজেক্ট তৈরি করে।
package main
import "fmt"
import "errors"
func main() {
err := errors.New("Something went wrong!")
fmt.Println(err) // আউটপুট: Something went wrong!
}এখানে, আমরা একটি নতুন error তৈরি করেছি এবং তা প্রিন্ট করেছি।
৪. Error Handling with Multiple Return Values
Go তে, আপনি একাধিক মান রিটার্ন করতে পারেন, একটি মান হতে পারে error টাইপ এবং অন্যটি মূল ডেটা (যেমন: ফলাফল)। সাধারণত error রিটার্ন ভ্যালু সর্বদা দ্বিতীয় ভ্যালু হিসেবে থাকে।
৪.১ Multiple Return Values Example
package main
import "fmt"
import "errors"
// একটি ফাংশন যা দুটি মান রিটার্ন করবে
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero error")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0) // 0 দিয়ে ভাগ করতে চেষ্টা করা হচ্ছে
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: division by zero error
} else {
fmt.Println("Result:", result)
}
}এখানে, divide ফাংশনটি দুটি রিটার্ন ভ্যালু রিটার্ন করেছে — একটি ফলাফল এবং একটি error। যদি error না থাকে, তবে ফলাফল প্রিন্ট হবে; অন্যথায়, error বার্তা প্রিন্ট হবে।
৫. Custom Error Types
Go তে আপনি নিজের error টাইপ তৈরি করতে পারেন, যা error interface implement করে এবং আপনার error মেসেজে অতিরিক্ত তথ্য যোগ করতে সাহায্য করে।
৫.১ Custom Error Type উদাহরণ
package main
import "fmt"
// Custom error type তৈরি করা
type DivisionError struct {
Message string
}
func (e *DivisionError) Error() string {
return e.Message
}
func divide(a, b int) (int, error) {
if b == 0 {
return 0, &DivisionError{"cannot divide by zero"}
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: cannot divide by zero
} else {
fmt.Println("Result:", result)
}
}এখানে, DivisionError নামক একটি custom error টাইপ তৈরি করা হয়েছে, যা Error() মেথড implement করে এবং এতে একটি কাস্টম মেসেজ রয়েছে। এই error টাইপটি divide ফাংশন দ্বারা রিটার্ন করা হয়েছে।
৬. Error Wrapping (Go 1.13)
Go 1.13 থেকে error wrapping এর ফিচার এসেছে, যেখানে আপনি একটি error কে অন্য একটি error এর মধ্যে লুকিয়ে (wrap) রাখতে পারেন। এর জন্য fmt.Errorf() এবং %w ফর্ম্যাট স্পেসিফায়ার ব্যবহার করা হয়।
৬.১ Error Wrapping উদাহরণ
package main
import (
"fmt"
"errors"
)
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero: %w", errors.New("invalid divisor"))
}
return a / b, nil
}
func main() {
_, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: division by zero: invalid divisor
}
}এখানে, fmt.Errorf() ব্যবহার করে একটি error কে অন্য error এর মধ্যে wrap করা হয়েছে এবং %w ফরম্যাট স্পেসিফায়ার ব্যবহার করা হয়েছে।
সারসংক্ষেপ
- Go-তে Error Handling: Go তে error handling সরাসরি error রিটার্ন ভ্যালু দিয়ে করা হয়। এটি explicit এবং সহজ।
- error Interface: Go তে
errorএকটি interface যাError()মেথড প্রদান করে। - Error Creation:
errors.New()এবং custom error টাইপ তৈরি করে error তৈরি করা যায়। - Multiple Return Values: Go তে error কে সাধারণত দ্বিতীয় রিটার্ন ভ্যালু হিসেবে রিটার্ন করা হয়।
- Error Wrapping: Go 1.13 এর পর
fmt.Errorf()এবং%wফরম্যাট স্পেসিফায়ার ব্যবহার করে error wrapping করা যায়।
Go তে error handling খুবই সোজা এবং শক্তিশালী, যা কোডে ত্রুটি ম্যানেজমেন্টকে সহজ এবং কার্যকর করে তোলে।
Go-তে error Interface এর ব্যবহার
Go প্রোগ্রামিং ভাষায়, error একটি বিল্ট-ইন interface, যা error handling সিস্টেমের অংশ। এই error interface দিয়ে, আপনি যে কোনো custom error তৈরি করতে পারেন যা আপনার কোডের মধ্যে নির্দিষ্ট ত্রুটি বা সমস্যাগুলি উপস্থাপন করে। Go তে ত্রুটির (error) ব্যবস্থাপনা সাধারণত error interface এর মাধ্যমে করা হয়, এবং এর সাহায্যে আপনার কোডকে আরও নির্ভুল এবং পরিষ্কারভাবে পরিচালনা করা যায়।
১. Go-তে error Interface কি?
Go-তে error একটি predefined interface, যার মধ্যে শুধুমাত্র একটি method থাকে:
type error interface {
Error() string
}Error(): এটি একটি method যা একটি string ফেরত দেয় এবং ত্রুটির বার্তা প্রদর্শন করে। এই method কে বাস্তবায়ন করে, আপনি কাস্টম error তৈরি করতে পারেন।
Go তে সাধারণত error interface ব্যবহার করে একটি ত্রুটি অবস্থান যাচাই করা হয় এবং প্রয়োজনে সেই error handling করা হয়।
২. Error Interface ব্যবহার
২.১ Built-in Error Handling
Go তে, error handling সাধারণত দুইটি ভ্যালু দিয়ে করা হয়:
- প্রথমটি: কোন function বা operation এর সফল ফলাফল।
- দ্বিতীয়টি: error যদি ঘটে থাকে।
package main
import (
"fmt"
"errors"
)
func divide(a, b int) (int, error) {
if b == 0 {
// error interface ব্যবহার করে error তৈরি করা
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: division by zero
} else {
fmt.Println("Result:", result)
}
}এখানে, divide ফাংশনে আমরা একটি error তৈরি করেছি যখন দ্বিতীয় সংখ্যাটি শূন্য (zero) হয়। আমরা errors.New() ব্যবহার করে একটি কাস্টম error বার্তা তৈরি করেছি, যা error interface পূর্ণ করেছে।
আউটপুট:
Error: division by zero২.২ Error Struct তৈরি করা
Go তে আপনি struct এর মাধ্যমে কাস্টম error তৈরি করতে পারেন এবং সেই struct-এ Error() method দিয়ে error interface বাস্তবায়ন করতে পারেন।
package main
import (
"fmt"
)
// Custom Error Struct
type DivisionError struct {
Dividend, Divisor int
}
func (e DivisionError) Error() string {
return fmt.Sprintf("cannot divide %d by %d", e.Dividend, e.Divisor)
}
func divide(a, b int) (int, error) {
if b == 0 {
// কাস্টম error তৈরি করা
return 0, DivisionError{a, b}
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: cannot divide 10 by 0
} else {
fmt.Println("Result:", result)
}
}এখানে, আমরা একটি DivisionError নামক struct তৈরি করেছি, যা error interface বাস্তবায়ন করেছে এবং Error() method-টির মাধ্যমে error বার্তা প্রদান করছে।
আউটপুট:
Error: cannot divide 10 by 0২.৩ Error Wrapping
Go 1.13 থেকে, fmt.Errorf ফাংশনটি error wrapping-এর সুবিধা দেয়, যার মাধ্যমে আপনি একটি existing error-কে নতুন বার্তা দিয়ে wrap করতে পারেন। এই ফিচারটি আপনাকে ত্রুটি সম্পর্কিত আরও বিস্তারিত তথ্য দিতে সহায়তা করে।
package main
import (
"fmt"
"errors"
)
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division failed: %w", errors.New("division by zero"))
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err) // আউটপুট: Error: division failed: division by zero
} else {
fmt.Println("Result:", result)
}
}এখানে, আমরা fmt.Errorf ব্যবহার করে একটি নতুন error তৈরি করেছি যা পুরানো error-টিকে wrap করে নতুন বার্তা প্রদান করছে।
আউটপুট:
Error: division failed: division by zero৩. Error Handling Practices
Go তে সাধারণত error handling দুটি অংশে বিভক্ত থাকে:
- Error চেকিং: ফাংশন বা অপারেশনে ত্রুটি ঘটে কিনা তা চেক করা।
- Error reporting: ত্রুটি ঘটলে তার তথ্য রিপোর্ট বা লগ করা।
এটি সাধারণত এইভাবে করা হয়:
if err != nil {
// Error handling code here
}৩.১ Multiple error handling
কখনো কখনো, একাধিক error চেকিং করা প্রয়োজন হতে পারে, যেমন ফাইল ওপেন করা এবং রিডিং, নেটওয়ার্ক কানেকশন তৈরি ইত্যাদি। এখানে multiple error handling এর একটি উদাহরণ:
package main
import (
"fmt"
"os"
)
func main() {
// ফাইল ওপেন করা
file, err := os.Open("non_existent_file.txt")
if err != nil {
fmt.Println("Error opening file:", err)
return
}
defer file.Close()
// ফাইলের মধ্যে কাজ করতে থাকা কোড...
}এখানে, আমরা os.Open ফাংশনে একটি error চেক করছি এবং ত্রুটি ঘটলে সেই error রিপোর্ট করছি।
সারসংক্ষেপ
errorInterface: Go-তেerrorএকটি বিল্ট-ইন interface যা একটিError()method ধারণ করে, যা ত্রুটির বার্তা প্রদান করে।- Custom Errors: Go-তে আপনি struct এর মাধ্যমে কাস্টম error তৈরি করতে পারেন এবং তা
Error()method দিয়েerrorinterface বাস্তবায়ন করতে পারেন। - Error Wrapping:
fmt.Errorfব্যবহার করে error wrapping করা সম্ভব, যা existing error এর সাথে নতুন বার্তা যোগ করতে সহায়তা করে। - Error Handling: Go তে ত্রুটি চেক এবং রিপোর্ট করার জন্য সাধারণত
if err != nilব্যবহার করা হয়।
Go-তে error interface ব্যবহার করে আপনি শক্তিশালী এবং পরিষ্কার error handling সিস্টেম তৈরি করতে পারবেন, যা আপনার কোডের স্টেবিলিটি এবং নির্ভুলতা বাড়ায়।
Go-তে Custom Errors তৈরি করা
Go প্রোগ্রামিং ভাষায় errors ব্যবস্থাপনা খুবই গুরুত্বপূর্ণ, কারণ এটি প্রোগ্রামিংয়ের স্থিতিশীলতা এবং কার্যকারিতা নিশ্চিত করে। Go তে বিল্ট-ইন error টাইপ আছে, যা সাধারণত একটি string ডেটা টাইপের সাথে যুক্ত থাকে এবং প্রোগ্রামের ত্রুটি বা সমস্যা নির্দেশ করে। তবে, আপনি চাইলে আপনার নিজের custom errors তৈরি করতে পারেন, যা আপনাকে নির্দিষ্ট ত্রুটির তথ্য বহন করতে সহায়তা করবে।
Go তে custom errors তৈরি করতে, সাধারণত একটি নতুন টাইপ (যেমন struct) তৈরি করা হয় এবং তাতে Error() মেথড যুক্ত করা হয়, যাতে এটি error interface সম্পূর্ণ করতে পারে। এর মাধ্যমে আপনি আরও বিস্তারিত ত্রুটি বার্তা দিতে পারেন।
১. Custom Error Types তৈরি করা
Go তে custom error তৈরি করতে, সাধারণত একটি struct তৈরি করা হয় এবং এতে Error() মেথড যুক্ত করা হয়, যা error interface-এ থাকার জন্য প্রয়োজনীয় ফাংশন।
১.১ Custom Error Definition
package main
import (
"fmt"
)
// Custom error type ডিফাইন করা
type MyError struct {
Code int
Message string
}
// Error() method যোগ করা
func (e *MyError) Error() string {
return fmt.Sprintf("Error Code: %d, Message: %s", e.Code, e.Message)
}
func main() {
// Custom error তৈরি
err := &MyError{
Code: 404,
Message: "Resource not found",
}
// Error প্রিন্ট করা
fmt.Println(err) // আউটপুট: Error Code: 404, Message: Resource not found
}এখানে, MyError struct তৈরি করা হয়েছে যা Code এবং Message ধারণ করে। Error() মেথডটি error interface-এ থাকার জন্য এটি প্রয়োজনীয় ফাংশন হিসাবে কাজ করে এবং কাস্টম ত্রুটির বার্তা প্রদান করে।
২. Custom Error এর সাথে Context যোগ করা
এটি আরও কার্যকরী করার জন্য, আপনি context যোগ করতে পারেন। এর মাধ্যমে আপনি ত্রুটির সাথে অতিরিক্ত তথ্য যেমন ফাইলের নাম, লাইনের নাম্বার ইত্যাদি সংযুক্ত করতে পারেন।
২.১ Custom Error with Context
package main
import (
"fmt"
)
// Custom error type with context
type MyError struct {
File string
Line int
Message string
}
// Error() method
func (e *MyError) Error() string {
return fmt.Sprintf("Error in file %s at line %d: %s", e.File, e.Line, e.Message)
}
func main() {
// Custom error with additional context
err := &MyError{
File: "main.go",
Line: 42,
Message: "Unable to open file",
}
// Error message with context
fmt.Println(err) // আউটপুট: Error in file main.go at line 42: Unable to open file
}এখানে, MyError struct এর মধ্যে File এবং Line যোগ করা হয়েছে, যা ত্রুটির সঠিক স্থান (context) জানাতে সহায়তা করে।
৩. Error Wrapping (এরর র্যাপিং)
Go 1.13 থেকে error wrapping ফিচার এসেছে, যার মাধ্যমে আপনি একটি ত্রুটির সাথে আরেকটি ত্রুটি যোগ করতে পারেন। এতে আগের ত্রুটির বিস্তারিত সংরক্ষিত থাকে এবং আপনি নতুন ত্রুটি দিতে পারেন।
৩.১ Error Wrapping Example
package main
import (
"fmt"
"errors"
)
// Custom error type
type MyError struct {
Code int
Message string
}
// Error() method
func (e *MyError) Error() string {
return fmt.Sprintf("Code: %d, Message: %s", e.Code, e.Message)
}
func main() {
// Initial error
err := &MyError{Code: 400, Message: "Bad Request"}
// Wrapping another error
wrappedError := fmt.Errorf("An error occurred: %w", err)
// Printing wrapped error
fmt.Println(wrappedError)
}এখানে, fmt.Errorf ব্যবহার করে একটি নতুন ত্রুটি তৈরি করা হয়েছে এবং আগের MyError ত্রুটির সাথে wrap করা হয়েছে। "%w" স্ট্রিং ফরম্যাট ব্যবহার করে ত্রুটির সাথে অন্য একটি ত্রুটি যুক্ত করা যায়।
আউটপুট:
An error occurred: Code: 400, Message: Bad Requestএটি wrappedError ত্রুটির মধ্যে আগের ত্রুটির সমস্ত তথ্য সংরক্ষণ করবে, যাতে আপনি সেই ত্রুটির বিশদ জানতে পারেন।
৪. Custom Error Handling এবং Type Assertion
আপনি যখন custom error তৈরি করেন, তখন type assertion ব্যবহার করে সেই error টাইপ চেক করতে পারেন এবং ত্রুটির আরও বিস্তারিত তথ্য পেতে পারেন।
৪.১ Type Assertion with Custom Error
package main
import (
"fmt"
)
// Custom error type
type MyError struct {
Code int
Message string
}
// Error() method
func (e *MyError) Error() string {
return fmt.Sprintf("Code: %d, Message: %s", e.Code, e.Message)
}
func processRequest() error {
return &MyError{Code: 404, Message: "Resource not found"}
}
func main() {
err := processRequest()
// Type assertion to check custom error
if myErr, ok := err.(*MyError); ok {
fmt.Println("Custom error occurred:")
fmt.Println("Code:", myErr.Code)
fmt.Println("Message:", myErr.Message)
} else {
fmt.Println("An error occurred:", err)
}
}এখানে, processRequest ফাংশন একটি custom error ফেরত দেয়, এবং আমরা type assertion ব্যবহার করে ত্রুটির ধরন চেক করছি। যদি এটি *MyError টাইপ হয়, তাহলে আমরা এর মান দেখতে পারি।
আউটপুট:
Custom error occurred:
Code: 404
Message: Resource not foundসারসংক্ষেপ
- Custom Errors: Go তে custom errors তৈরি করতে আপনি একটি struct তৈরি করেন এবং তাতে
Error()মেথড যোগ করেন। - Error Wrapping: Go 1.13 থেকে error wrapping ফিচার পাওয়া যায়, যার মাধ্যমে আপনি ত্রুটির মধ্যে আরেকটি ত্রুটি সংযুক্ত করতে পারেন।
- Type Assertion: custom errors ব্যবহারের ক্ষেত্রে,
type assertionব্যবহার করে আপনি ত্রুটির বিস্তারিত তথ্য অ্যাক্সেস করতে পারেন।
Custom errors তৈরি করার মাধ্যমে আপনি আপনার Go প্রোগ্রামে ত্রুটি হ্যান্ডলিং আরও উন্নত করতে পারেন, যার মাধ্যমে ত্রুটির উৎস এবং প্রসঙ্গ ভালোভাবে ট্র্যাক করা সম্ভব হয়।
Go তে Error Wrapping এবং Unwrapping এর ব্যবহার
Go প্রোগ্রামিং ভাষায় Error Handling খুবই গুরুত্বপূর্ণ, এবং Go-তে সাধারণত error টাইপ ব্যবহার করে ত্রুটি (error) পরিচালনা করা হয়। Go 1.13 থেকে error wrapping এবং unwrapping এর সুবিধা এসেছে, যা ত্রুটির মধ্যে অতিরিক্ত তথ্য সংরক্ষণ করতে এবং সেই ত্রুটির উৎস সন্ধান করতে সাহায্য করে। এই ফিচারের মাধ্যমে আপনি ত্রুটির শিকড় বুঝতে এবং ডিবাগিং করতে আরও সহজ এবং কার্যকরী উপায় পেতে পারেন।
১. Error Wrapping (এরর র্যাপিং)
Error wrapping হল একটি প্রক্রিয়া যেখানে একটি ত্রুটির (error) উপর অতিরিক্ত কনটেক্সট (context) বা তথ্য যোগ করা হয়। Go 1.13 এ, fmt.Errorf ফাংশনের মাধ্যমে error wrapping এর সুবিধা সংযুক্ত করা হয়েছে।
১.১ Error Wrapping উদাহরণ
package main
import (
"fmt"
"errors"
)
func main() {
// একটি বেসিক ত্রুটি তৈরি
err := errors.New("file not found")
// Error wrapping - অতিরিক্ত তথ্য সহ ত্রুটির র্যাপিং করা
wrappedErr := fmt.Errorf("failed to open file: %w", err)
// র্যাপ করা ত্রুটি প্রিন্ট করা
fmt.Println(wrappedErr)
}এখানে, fmt.Errorf ফাংশনটি file not found ত্রুটির উপর অতিরিক্ত কনটেক্সট যোগ করেছে। fmt.Errorf এর "%w" ফরম্যাট স্পেসিফায়ারটি ত্রুটির মধ্যে পূর্ববর্তী ত্রুটিকে র্যাপ করতে ব্যবহৃত হয়। এই র্যাপিংয়ে নতুন ত্রুটি তৈরি হয় যা মূল ত্রুটির সাথে সম্পর্কিত তথ্য ধারণ করে।
আউটপুট:
failed to open file: file not found১.২ Error Wrapping এর সুবিধা
- Contextual Information: ত্রুটির সাথে অতিরিক্ত কনটেক্সট যোগ করা হয়, যেমন কোথায় ত্রুটিটি ঘটেছে বা কি কারণে তা ঘটেছে।
- Chaining Errors: আপনি একাধিক স্তরের ত্রুটি যোগ করতে পারেন, এবং প্রতিটি স্তরের সাথে পূর্ববর্তী ত্রুটির তথ্য সংরক্ষণ করতে পারেন।
২. Error Unwrapping (এরর আনর্যাপিং)
Error unwrapping হল একটি প্রক্রিয়া যা আপনাকে একটি র্যাপ করা ত্রুটির মধ্যে আসল ত্রুটিটি বের করতে (unwrap) সাহায্য করে। Go 1.13 এর পর errors.Is এবং errors.As ফাংশনগুলির মাধ্যমে ত্রুটির মধ্যে একটি নির্দিষ্ট ত্রুটি চেক করতে সক্ষম হন, যা আপনাকে ত্রুটির উত্স বা মূল ত্রুটি বের করতে সহায়তা করে।
২.১ Error Unwrapping উদাহরণ
package main
import (
"fmt"
"errors"
)
func main() {
// একটি বেসিক ত্রুটি তৈরি
err := errors.New("file not found")
// Error wrapping - অতিরিক্ত তথ্য সহ ত্রুটির র্যাপিং করা
wrappedErr := fmt.Errorf("failed to open file: %w", err)
// Error Unwrapping - ত্রুটির মধ্যে আসল ত্রুটিটি বের করা
if errors.Is(wrappedErr, err) {
fmt.Println("Original error:", err)
} else {
fmt.Println("No match found")
}
}এখানে, errors.Is ফাংশনটি ব্যবহৃত হয়েছে, যা র্যাপ করা ত্রুটির মধ্যে মূল ত্রুটির সাথে তুলনা করে। যদি মূল ত্রুটি মেলে, তাহলে আমরা wrappedErr থেকে আসল ত্রুটিটি বের করতে পারি।
আউটপুট:
Original error: file not found২.২ errors.Is এবং errors.As
errors.Is: এটি মূল ত্রুটির সাথে তুলনা করতে ব্যবহৃত হয়। এটি নির্দিষ্ট একটি ত্রুটির উপস্থিতি চেক করে।errors.As: এটি নির্দিষ্ট ত্রুটির টাইপ বের করতে ব্যবহৃত হয়। এটি মূল ত্রুটির মধ্যে একটি নির্দিষ্ট ত্রুটি টাইপ অ্যাসাইন করতে সাহায্য করে।
২.৩ errors.As এর ব্যবহার
package main
import (
"fmt"
"errors"
)
type customError struct {
msg string
}
func (e *customError) Error() string {
return e.msg
}
func main() {
// একটি custom error তৈরি
err := &customError{msg: "This is a custom error"}
// Error wrapping
wrappedErr := fmt.Errorf("wrapped error: %w", err)
// Error unwrapping using errors.As to extract customError
var ce *customError
if errors.As(wrappedErr, &ce) {
fmt.Println("Unwrapped error:", ce)
} else {
fmt.Println("No custom error found")
}
}এখানে, errors.As ব্যবহার করে আমরা একটি customError টাইপের ত্রুটি বের করেছি, যেটি wrappedErr এর মধ্যে রয়েছে।
আউটপুট:
Unwrapped error: This is a custom error৩. Error Wrapping এবং Unwrapping এর সুবিধা
- Chaining Errors: error wrapping এর মাধ্যমে আপনি ত্রুটির একটি শৃঙ্খলা তৈরি করতে পারেন, যেখানে প্রতিটি ত্রুটি পূর্ববর্তী ত্রুটির তথ্য ধারণ করে।
- Contextual Errors: Wrapping এর মাধ্যমে ত্রুটির সাথে অতিরিক্ত কনটেক্সট বা ডেটা যোগ করতে পারবেন, যাতে ত্রুটি বিশ্লেষণ এবং ডিবাগিং সহজ হয়।
- Unwrapping for Debugging: error unwrapping এর মাধ্যমে আপনি মূল ত্রুটির উৎস খুঁজে বের করতে পারবেন, যা ডিবাগিং এবং ত্রুটি মোকাবেলায় সহায়ক।
সারসংক্ষেপ
- Error Wrapping: Go 1.13 থেকে ত্রুটির উপর অতিরিক্ত কনটেক্সট বা তথ্য যোগ করার জন্য
fmt.Errorfফাংশনটি%wফরম্যাট স্পেসিফায়ার ব্যবহার করে error wrapping সম্ভব করেছে। - Error Unwrapping:
errors.Isএবংerrors.Asফাংশনগুলো ব্যবহার করে, আপনি র্যাপ করা ত্রুটির মধ্যে মূল ত্রুটিটি বের করতে পারেন এবং তা নির্দিষ্ট টাইপের সাথে মেলানোর চেষ্টা করতে পারেন। - Error Wrapping এবং Unwrapping এর মাধ্যমে আপনি ত্রুটির বিশ্লেষণ, ডিবাগিং এবং কোডের কার্যকারিতা আরো উন্নত এবং মজবুত করতে পারেন।
Read more