RxJS-এ Error Handling একটি গুরুত্বপূর্ণ অংশ, বিশেষত যখন আপনি অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং করছেন এবং বিভিন্ন স্ট্রিম বা অপারেশনগুলিতে ত্রুটি (error) ঘটতে পারে। RxJS এর বিভিন্ন অপারেটর রয়েছে যা error handling সহজ এবং কার্যকরী করতে সাহায্য করে। যখন অ্যাসিঙ্ক্রোনাস অপারেশনগুলোতে ত্রুটি ঘটে, তখন আপনি catchError, retry, retryWhen ইত্যাদি অপারেটর ব্যবহার করে সেই ত্রুটির মোকাবিলা করতে পারেন।
এখানে, আমরা দেখব কিভাবে error handling অপারেটরগুলো RxJS স্ট্রিমে প্রয়োগ করা যায়।
1. catchError() অপারেটর
catchError() অপারেটরটি ত্রুটি ঘটলে তাকে ধরা এবং তা সমাধান বা পুনরায় চেষ্টা করার জন্য ব্যবহৃত হয়। এটি একটি fallback Observable প্রদান করতে সাহায্য করে যখন মূল Observable-এ কোনো ত্রুটি ঘটে।
বৈশিষ্ট্য:
- Fallback Observable: যখন কোনো ত্রুটি ঘটে, তখন আপনি একটি নতুন Observable ফিরিয়ে দিতে পারেন।
- Error Recovery: এটি মূল স্ট্রিমের ত্রুটিকে "ধরে" এবং আপনাকে ত্রুটির স্থলে অন্য একটি Observable পাঠানোর সুযোগ দেয়।
উদাহরণ:
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';
const source$ = new Observable((observer) => {
observer.next('First value');
observer.next('Second value');
observer.error('An error occurred'); // Error occurs here
});
source$.pipe(
catchError((error) => {
console.log('Caught error:', error);
return of('Fallback value'); // Return a fallback value in case of error
})
).subscribe({
next: (value) => console.log('Received:', value),
error: (err) => console.log('Error:', err),
complete: () => console.log('Completed'),
});
আউটপুট:
Received: First value
Received: Second value
Caught error: An error occurred
Received: Fallback value
Completed
এখানে, যখন ত্রুটি ঘটলো, তখন catchError() fallback value 'Fallback value' পাঠিয়েছে, এবং ত্রুটি সমাধান হয়েছে।
2. retry() অপারেটর
retry() অপারেটরটি ত্রুটি ঘটলে মূল Observable কে পুনরায় চেষ্টা (retry) করতে বলে। আপনি কতবার পুনরায় চেষ্টা করতে চান, তা নির্ধারণ করতে পারেন।
বৈশিষ্ট:
- Retry Limit: নির্দিষ্ট সংখ্যক বার পুনরায় চেষ্টা করতে পারে।
- Error Recovery: যদি Observable ত্রুটি না দেয়, তবে পুনরায় চেষ্টা করা হয় যতক্ষণ না সেটি সফল না হয়।
উদাহরণ:
import { of, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
const source$ = new Observable((observer) => {
observer.next('First value');
observer.next('Second value');
observer.error('An error occurred'); // Error occurs here
});
source$.pipe(
retry(2), // Retry up to 2 times
catchError((error) => {
console.log('Caught error after retries:', error);
return of('Fallback value'); // Return a fallback value if retries fail
})
).subscribe({
next: (value) => console.log('Received:', value),
error: (err) => console.log('Error:', err),
complete: () => console.log('Completed'),
});
আউটপুট:
Received: First value
Received: Second value
Caught error after retries: An error occurred
Received: Fallback value
Completed
এখানে, retry(2) অপারেটরটি ত্রুটির পরে ২ বার পুনরায় চেষ্টা করেছে, কিন্তু ত্রুটি অব্যাহত থাকায় catchError() ফ্লেকব্যাক ভ্যালু পাঠিয়েছে।
3. retryWhen() অপারেটর
retryWhen() অপারেটরটি একটু ভিন্নভাবে কাজ করে। এটি যখন ত্রুটি ঘটে, তখন নির্দিষ্ট শর্তে Observable-কে পুনরায় চেষ্টা (retry) করার জন্য ব্যবহৃত হয়। আপনি একটি Notifiable Observable প্রদান করতে পারেন, যা শর্ত পূর্ণ হলে পুনরায় চেষ্টা করবে।
বৈশিষ্ট:
- Custom Retry Logic: এটি আপনাকে কাস্টম লজিক তৈরি করতে সাহায্য করে, যেমন একটি বিলম্ব (delay) বা পুনরায় চেষ্টা করার শর্ত।
উদাহরণ:
import { of, throwError } from 'rxjs';
import { retryWhen, delay, mergeMap } from 'rxjs/operators';
const source$ = new Observable((observer) => {
observer.next('First value');
observer.next('Second value');
observer.error('An error occurred'); // Error occurs here
});
source$.pipe(
retryWhen(errors =>
errors.pipe(
mergeMap((error, index) => {
if (index < 2) {
console.log(`Retrying... attempt #${index + 1}`);
return of(error).pipe(delay(1000)); // Retry after 1 second
}
return throwError('Retries failed'); // After 2 retries, throw error
})
)
)
).subscribe({
next: (value) => console.log('Received:', value),
error: (err) => console.log('Error:', err),
complete: () => console.log('Completed'),
});
আউটপুট:
Retrying... attempt #1
Retrying... attempt #2
Error: Retries failed
এখানে, retryWhen() ত্রুটির পরে পুনরায় চেষ্টা করেছে এবং delay(1000) দিয়ে ১ সেকেন্ড পর পর পুনরায় চেষ্টা করেছে। ২ বার চেষ্টা করার পরে, ত্রুটি ফিরে এসেছে।
4. throwError() - Error সৃষ্টি করা
throwError() অপারেটরটি একটি নতুন Observable তৈরি করে যা একটি ত্রুটি ছুড়ে দেয়। এটি তখন ব্যবহৃত হয় যখন আপনি manual error throwing করতে চান।
উদাহরণ:
import { throwError } from 'rxjs';
const error$ = throwError('An intentional error occurred');
error$.subscribe({
next: (value) => console.log('Received:', value),
error: (err) => console.log('Caught error:', err),
complete: () => console.log('Completed'),
});
আউটপুট:
Caught error: An intentional error occurred
এখানে, throwError() একটি কৃত্রিম ত্রুটি তৈরি করেছে, এবং সাবস্ক্রাইবার ত্রুটি ধরেছে।
সারাংশ
RxJS-এ error handling এর জন্য বিভিন্ন অপারেটর ব্যবহার করা যায়, যা অ্যাসিঙ্ক্রোনাস স্ট্রিমে ত্রুটি পরিচালনা করার ক্ষেত্রে সহায়ক। গুরুত্বপূর্ণ অপারেটরগুলো হলো:
- catchError(): ত্রুটি ঘটলে তাকে ধরতে এবং একটি নতুন Observable বা fallback value প্রদান করতে ব্যবহৃত হয়।
- retry(): ত্রুটি ঘটলে নির্দিষ্ট সংখ্যক বার পুনরায় চেষ্টা করে।
- retryWhen(): কাস্টম পুনরায় চেষ্টা করার লজিক তৈরির জন্য ব্যবহৃত হয়।
- throwError(): কৃত্রিম ত্রুটি তৈরি করতে ব্যবহৃত হয়।
এই অপারেটরগুলির মাধ্যমে আপনি রিয়্যাক্টিভ প্রোগ্রামিংয়ে ত্রুটির সমস্যা ম্যানেজ করে ডেটা প্রক্রিয়াকরণকে আরও শক্তিশালী এবং নির্ভরযোগ্য করতে পারেন।
Read more