میں نے کلائنٹ سائیڈ ایرر رپورٹنگ اس لیے بنائی تھی تاکہ حقیقی صارفین کے وہ مسائل دیکھ سکوں جنہیں مقامی ماحول میں قابلِ اعتماد طریقے سے دوبارہ پیدا کرنا مشکل تھا۔ رپورٹر وہی کر رہا تھا جو میں نے کہا تھا: خرابی پکڑو اور مجھے بھیج دو۔
مسئلہ یہ تھا کہ تقریباً ہر چیز ایک جتنی اہم دکھائی دیتی تھی۔
کوئی بیرونی اینالیٹکس اسکرپٹ لوڈ نہیں ہوا؟ سرخ الرٹ۔ اشتہار کا اسکرپٹ بلاک ہوا؟ سرخ الرٹ۔ کوئی کرالر Google Analytics لوڈ نہیں کر سکا؟ سرخ الرٹ۔ ویڈیو پری ویو نے play() چلایا اور Promise مکمل ہونے سے پہلے رک گیا؟ سرخ الرٹ۔ مفید ماخذ یا اسٹیک کے بغیر Script error. آیا؟ پھر سرخ الرٹ۔
اسی سلسلے میں وہ خرابیاں بھی تھیں جن پر واقعی کام کرنا چاہیے تھا: میری ایپ کا URL غلطی سے https://example.comhttps://example.com/... بن گیا تھا، اور براؤزر /_next/static/chunks/... کے اندر میری ایپ کی Next.js فائل لوڈ نہیں کر سکا تھا۔
جمع آوری کی تہہ کام کر رہی تھی۔ مانیٹرنگ کی تہہ نہیں۔
اس فرق نے فرنٹ اینڈ آبزرویبلٹی کے بارے میں میری سوچ بدل دی۔ ایرر ایونٹ صرف اس بات کا ثبوت ہے کہ کچھ ہوا۔ وہ ابھی تشخیص، سنگینی کی سطح یا کوئی واقعہ نہیں ہے۔
پہلی غلطی “ایرر” کو خود بخود “فوری” سمجھ لینا تھی
ابتدائی ذہنی ماڈل تقریباً یہ تھا:
browser error report کرتا ہے
↓
CLIENT ERROR بھیجو
↓
developer کو فوراً دیکھنا چاہیے
اس ماڈل میں کئی الگ سوال ایک ساتھ مل گئے تھے۔ کیا خرابی میرے کوڈ میں ہے؟ کیا فعال روٹ واقعی ٹوٹا ہے؟ کیا یہ متوقع منسوخی تھی؟ کیا براؤزر کے پاس ماخذ پہچاننے کے لیے کافی معلومات ہیں؟ کیا ایپ بحال ہوئی؟ دس پیغامات دس واقعات ہیں یا ایک واقعے کی دس علامات؟
ان سوالوں کے جواب سے پہلے کسی ایونٹ کو خودکار طور پر الرٹ نہیں بننا چاہیے۔
ایک ابتدائی جائزے میں میرے سامنے تقریباً اٹھارہ پیغامات تھے۔ زیادہ تر بیرونی خدمات یا معمول کے لائف سائیکل کا شور تھے۔ دو معاملات صاف الگ تھے: میری ایپ کا بگڑا ہوا URL واضح بگ تھا، جبکہ میری ایپ کا JavaScript چنک لوڈ نہ ہونا صفحے کو ضروری کوڈ سے محروم کر سکتا تھا۔ پھر بھی رپورٹر تقریباً سب کو بلاک ہوئے اشتہار جتنی فوری اہمیت دے رہا تھا۔
یہیں سے میں نے “تمام براؤزر ایررز جمع کرنا” اور “پروڈکشن مانیٹرنگ بنانا” الگ مسائل سمجھنا شروع کیے۔ جمع آوری شواہد محفوظ کرتی ہے؛ مانیٹرنگ ان شواہد کو فیصلوں میں بدلتی ہے۔
براؤزر کے پاس ہر خرابی کے لیے ایک ہی معنی رکھنے والا کوئی واحد ایرر چینل نہیں ہے
کلائنٹ کی مختلف ناکامیاں ایک جیسی معنویت کے ساتھ نہیں آتیں۔
window کا error ایونٹ ہم وقت اسکرپٹ ایررز کے لیے استعمال ہوتا ہے اور ریسورس لوڈنگ کی ناکامیوں میں بھی کردار رکھتا ہے۔ بغیر ہینڈل کی گئی Promise rejection الگ راستے سے جاتی ہے اور براؤزر unhandledrejection بھیجتا ہے۔ اسکرپٹ، تصویر یا میڈیا لوڈ کرنے والے عناصر اپنے error ایونٹس بھی دے سکتے ہیں۔ React اور Next.js اس کے اوپر فریم ورک کی ایرر باؤنڈری کے سگنل شامل کرتے ہیں۔
window.error
→ synchronous script error باہر نکلا ہو سکتا ہے
unhandledrejection
→ rejected Promise اس وقت handle نہیں ہوئی تھی
element error
→ resource load یا use نہیں ہو سکا
framework boundary
→ rendering یا execution error boundary تک پہنچا
گلوبل ہُک سسٹم کی حد پر نظر آنے والی علامت دیکھتا ہے؛ ضروری نہیں کہ اسے پوری سبب کی زنجیر معلوم ہو۔
یہ فرق سمجھنے کے بعد میں نے ہر ایونٹ کو فوراً ایک عام Error اور ایک ہی سنگینی میں ڈالنا چھوڑ دیا۔
ملکیت پہلا مفید فلٹر ہے
شور کم کرنے والا پہلا مفید فرق یہ تھا کہ ناکام کوڈ یا ریسورس کس کا ہے۔
/_next/static/chunks/app/... کا لوڈ نہ ہونا کسی دوسرے اوریجن پر اشتہاری SDK کی ناکامی جیسا نہیں۔ میرے URL بلڈر کا غلط URL بنانا بلاک ہوئی اینالیٹکس درخواست جیسا نہیں۔ براؤزر ایکسٹینشن کا ایرر ایک الگ زمرہ ہے۔
- اپنی ایپ: میرا JavaScript، CSS، API، میڈیا اور میرے کوڈ کے بنائے ہوئے URL؛
- فریم ورک اور رن ٹائم: ایپ کے اجرا کے راستے میں آنے والے Next.js یا React؛
- بیرونی انٹیگریشن: اینالیٹکس، اشتہارات، ویجٹس اور بیرونی SDK؛
- ماحول: براؤزر ایکسٹینشنز، کرالرز، نیٹ ورک کی حالت، رازداری کے اوزار اور براؤزر مخصوص رویہ۔
اس کا مطلب یہ نہیں کہ بیرونی خدمات غیر اہم ہیں۔ ادائیگی یا توثیق کا فراہم کنندہ انتہائی اہم ہو سکتا ہے، اور اشتہارات کی ناکامی آمدنی کو متاثر کر سکتی ہے۔ مگر انٹیگریشن کی خراب حالت خود بخود ایپ کریش نہیں ہے۔
اگر سب کچھ ایک ہی فوری الرٹ چینل میں جائے تو اس چینل کا مطلب ختم ہو جاتا ہے۔
اپنی ایپ کی دو ناکامیوں نے مجھے سمجھایا کہ “قابلِ عمل” سگنل کیا ہوتا ہے
غلط بنا ہوا URL والا معاملہ آسان تھا:
https://example.comhttps://example.com/resource
اس معاملے میں AdBlock، VPN یا براؤزر پالیسی پر نظریے بنانے کی ضرورت نہیں تھی۔ URL خود غلط تھا۔ کہیں کوڈ ایسے قدر کے آگے اوریجن لگا رہا تھا جو پہلے ہی مکمل URL تھی۔
یہ ایونٹ قابلِ عمل تھا کیونکہ ثبوت واضح تھا، ریسورس میرا تھا اور مسئلہ براہِ راست ایسے کوڈ راستے کی طرف اشارہ کر رہا تھا جسے میں کنٹرول کرتا ہوں۔
Next.js چنک کی ناکامی مختلف تھی:
Failed to load script:
/_next/static/chunks/9253.647385b4be0958e4.js
وہ بھی میری ایپ کا تھا اور صفحہ توڑ سکتا تھا، مگر ایونٹ وجہ ثابت نہیں کرتا تھا۔ پرانا کلائنٹ پچھلی تعیناتی کی فائل مانگ سکتا تھا؛ درخواست ٹائم آؤٹ ہو سکتی تھی؛ ریورس پراکسی یا CDN ناکام ہو سکتا تھا؛ کنکشن کٹ سکتا تھا؛ یا فائل واقعی غائب ہو سکتی تھی۔
صحیح ردعمل “مجھے وجہ معلوم ہے” نہیں، بلکہ “اس قسم کی ترجیح زیادہ ہے اور مزید سیاق چاہیے” تھا۔
وجہ پر یقین کم ہو تب بھی سنگینی زیادہ ہو سکتی ہے۔
Script error. ایک سراغ ہے، اسٹیک ٹریس نہیں
Error: Script error.
filename: unknown
line: 0
column: 0
یہ خوفناک لگتا ہے مگر تقریباً کچھ نہیں بتاتا۔
براؤزر کراس اوریجن اسکرپٹ ایررز کی تفصیل جان بوجھ کر محدود کرتے ہیں۔ MDN کے مطابق درست CORS ترتیب کے بغیر window.onerror کو محدود معلومات ملتی ہیں؛ <script> کا crossorigin رویہ براہِ راست طے کرتا ہے کہ مکمل ایرر معلومات دستیاب ہوں گی یا نہیں۔
اسی لیے میں مبہم Script error. دیکھ کر خودکار طور پر “میری ایپ کریش ہو گئی” نہیں مانتا۔ ماخذ میرا کوڈ، کسی تیسرے فریق کا کوڈ، انجیکٹ کیا گیا کوڈ، یا ایسا ایرر ہو سکتا ہے جس کی تفصیل براؤزر کراس اوریجن پابندی کے باعث ظاہر نہ کر سکے۔
میں ایونٹ محفوظ رکھتا ہوں اور اسے صفحے، بلڈ، براؤزر اور قریب کے ایونٹس سے جوڑتا ہوں، مگر اکیلا 0:0 فوری الرٹ کے لیے کافی نہیں۔ اگر یہی پیٹرن کسی ایک ریلیز یا روٹ کے گرد جمع ہونے لگے تو ترجیح بدلتی ہے۔
نامعلوم کا مطلب بے ضرر نہیں۔ اس کا مطلب سنگین بھی نہیں۔
AbortError بالکل حقیقی ایرر ہو سکتا ہے اور پھر بھی معمول کے لائف سائیکل کا حصہ ہو سکتا ہے
ویڈیو پری ویو نے اس فرق کی سب سے صاف مثال دی:
AbortError:
The play() request was interrupted by a call to pause()
HTMLMediaElement.play() ایک Promise لوٹاتا ہے اور وہ Promise مسترد ہو سکتی ہے۔ میڈیا لائف سائیکل کی کارروائیاں زیرِ انتظار پلے بیک کو جان بوجھ کر روک سکتی ہیں؛ MDN واضح طور پر لکھتا ہے کہ load() زیرِ انتظار play() Promise کو AbortError کے ساتھ منسوخ کرتا ہے۔
پری ویو گرڈ میں یہ صارف کو کوئی خرابی دکھائے بغیر آسانی سے ہو سکتا ہے۔ آئٹم viewport میں آتا ہے، کوڈ play() چلاتا ہے؛ صارف اسکرول کرتا ہے، آئٹم باہر چلا جاتا ہے؛ پلے بیک شروع ہونے سے پہلے کوڈ میڈیا روک دیتا ہے یا بدل دیتا ہے۔
Promise کا مسترد ہونا حقیقی ہے۔ صارف کے لیے کوئی واقعہ شاید موجود ہی نہ ہو۔
صحیح حل عموماً اسی کال کے قریب ہوتا ہے: Promise وہیں سنبھالنا اور متوقع منسوخی کو اصل پلے بیک ناکامی سے الگ کرنا۔ unhandledrejection حفاظتی جال ہو سکتا ہے، مگر معمول کے میڈیا لائف سائیکل کو پہلی بار سمجھنے کی جگہ نہیں۔
بیرونی خدمات کی ناکامیوں کے لیے الگ صحت کا ماڈل چاہیے
میرے ابتدائی لاگز میں اینالیٹکس اور اشتہاری ڈومینز کی بہت سی ناکامیاں تھیں۔ کچھ رازداری پر زور دینے والے براؤزرز سے آتی تھیں، کچھ کرالرز سے۔ خاص طور پر بے فائدہ فوری الرٹ یہ تھا کہ کوئی کرالر Google Analytics لوڈ نہیں کر سکا۔
یہ صرف بتاتا ہے کہ ایک نیٹ ورک درخواست ناکام ہوئی۔ اس سے تقریباً کچھ نہیں پتا چلتا کہ انسانی صارف ایپ استعمال کر پایا یا نہیں۔
ایونٹ محفوظ کرنا غلطی نہیں تھی۔ غلطی یہ تھی کہ اسے میری ایپ کے لوڈ نہ ہونے والے JavaScript چنک کے ساتھ اسی واقعاتی سلسلے میں ڈال دیا۔
- کیا ایپ صارف کے لیے واقعی ٹوٹ گئی ہے؟
- کیا بیرونی انٹیگریشن صحیح چل رہا ہے؟
بلاک ہوا اشتہاری اسکرپٹ اشتہار رسانی کی میٹرک میں جا سکتا ہے۔ اینالیٹکس کی ناکامی اینالیٹکس کوریج کی میٹرک بن سکتی ہے۔ جب تک بنیادی فعالیت واقعی ان پر منحصر نہ ہو، کسی کو بھی “فرنٹ اینڈ کریش” کہہ کر فوری الرٹ نہیں بنانا چاہیے۔
الگ کرنے سے بیرونی مسائل اور واضح ہوتے ہیں: انہیں فراہم کنندہ، براؤزر اور خطے کے حساب سے گروپ کیا جا سکتا ہے، بے ترتیب سرخ شور کی طرح نہیں۔
navigator.onLine سیاق دیتا ہے، رابطے کا ثبوت نہیں
میں نے یہ بھی لاگ کرنا شروع کیا کہ براؤزر خود کو آن لائن سمجھتا ہے یا نہیں۔ یہ معلومات مفید ہیں، مگر صرف اشارے کے طور پر۔
کچھ ایونٹس کو اضافی منطق نے نیٹ ورک ناکامی کہا، جبکہ اسی لاگ میں لکھا تھا:
Online: true
یہ تضاد نہیں ہے۔ MDN صاف خبردار کرتا ہے کہ navigator.onLine براؤزر اور آپریٹنگ سسٹم کے اندازوں پر مبنی ہے۔ مشین مقامی نیٹ ورک سے جڑی ہو سکتی ہے مگر پھر بھی میرے اوریجن تک نہ پہنچ سکے۔ VPN، فائر وال، DNS اور جزوی نیٹ ورک بندش تصویر کو مزید پیچیدہ بناتے ہیں۔
online === false
→ environment problem کا strong hint
online === true
→ origin یا resource reachable ہونے کا proof نہیں
یہ چھوٹا فرق مانیٹرنگ سسٹم کو کسی اشارے کو پراعتماد مگر غلط تشخیص میں بدلنے سے روکتا ہے۔
ایک بنیادی ناکامی کئی براؤزر ایونٹس پیدا کر سکتی ہے
جمع آوری بہتر ہونے کے بعد ایک اور قسم کا شور واضح ہوا: ایک واقعہ کئی پیغامات پیدا کر سکتا ہے۔
JavaScript چنک پہلے resource.error دے سکتا ہے، پھر ماڈیول لوڈر ChunkLoadError پھینک سکتا ہے، React یا Next.js ایرر باؤنڈری پار کر سکتے ہیں، اور بحالی کی منطق ری لوڈ طے کر سکتی ہے۔ اگر ہر تہہ الگ الرٹ بھیجے تو صارف کی ایک کارروائی کئی الگ پروڈکشن ناکامیوں جیسی لگتی ہے۔
پانچ پیغامات ذہنی طور پر پانچ متاثرہ صارفین جیسے لگتے ہیں، حالانکہ سب ایک ہی سیشن اور ایک ہی ریسورس سے آ سکتے ہیں۔
صرف پیغام کے متن سے تکرار ہٹانا کافی نہیں۔ واقعے کی سطح پر باہمی ربط چاہیے:
session
+ مختصر time window
+ normalized error class
+ first-party resource
+ client build
+ route
میں خام ایونٹس محفوظ رکھتا ہوں، مگر انسان تک وہی واقعہ پہنچنا چاہیے جس میں سب سے مضبوط سگنل ہو۔ اگر ایرر باؤنڈری میں میرے کوڈ کا اسٹیک اور چنک کا درست URL پہلے ہی موجود ہے تو اس سے پہلے آیا عام ریسورس ایرر دوسرے فوری الرٹ کی ضرورت نہیں رکھتا۔
الرٹ واقعات پر کریں، ایونٹس محفوظ رکھیں۔
ایرر کے آس پاس کا سیاق بعد میں ایرر اسٹرنگ سے زیادہ قیمتی ثابت ہوا
بعد کی ٹیلی میٹری کہیں زیادہ منظم ہو گئی:
clientBuildId
resource URL
resourceResponseStatus
resourceTransferSize
resourceDurationMs
serviceWorkerVersion
serviceWorkerController
serviceWorkerState
chunkRecoveryScheduled
online
stack / component stack
میڈیا کے لیے میں میڈیا ایرر کوڈ، الگ سے نظر آنے پر HTTP اسٹیٹس، حقیقی Content-Type، اور یہ بھی محفوظ کرتا تھا کہ ناکامی HTTP کی لگتی ہے یا نیٹ ورک ترسیل کی۔
ان فیلڈز نے وہ سوال پوچھنے ممکن کیے جن کا ایک عام استثنا متن جواب نہیں دیتا: کیا ناکامیاں ایک خاص بلڈ سے شروع ہوئیں؟ کیا براؤزر نے HTTP جواب لیا؟ کیا Service Worker صفحہ کنٹرول کر رہا تھا؟ کیا بحالی کی منطق چل چکی تھی؟ کیا کئی ایونٹس ایک ہی ریسورس کی طرف اشارہ کر رہے تھے؟ کیا موجودہ روٹ واقعی متاثر ہوا؟
Resource Timing API ریسورس کا دورانیہ، ٹرانسفر معلومات اور جہاں معاونت و اجازت ہو وہاں جواب کا اسٹیٹس دے سکتا ہے۔ اس کی حدیں ہیں: کراس اوریجن ٹائمنگ محدود ہے، کیش شدہ ریسورس میں transferSize: 0 ہو سکتا ہے، اور responseStatus ہر جگہ دستیاب نہیں۔ اس لیے null اور 0 کو بامعنی حالتیں رہنا چاہیے، جعلی یقین نہیں۔
ChunkLoadError ایک علامت ہے، 404 ڈٹیکٹر نہیں
بعد کے ایک ایونٹ نے چنک ناکامیوں کو پڑھنے کا میرا طریقہ بدل دیا۔
براؤزر نے Next.js کے layout چنک کے لیے ChunkLoadError بتایا، جبکہ بہتر ٹیلی میٹری میں ساتھ ہی یہ بھی تھا:
resourceResponseStatus: 200
resourceDurationMs: 170523
serviceWorkerState: activated
chunkRecoveryScheduled: true
ریکارڈ شدہ دورانیہ تقریباً 170 سیکنڈ تھا۔ اس واقعے کی اصل جڑ جو بھی رہی ہو، یہ معلومات حد سے زیادہ سادہ ایک قاعدہ رد کرنے کے لیے کافی تھیں:
ChunkLoadError === server نے 404 دیا
دوسری چنک ناکامیوں میں کوئی قابلِ مشاہدہ جواب اسٹیٹس نہیں تھا۔ کچھ ٹائم آؤٹ کی صورت میں آئیں، کچھ میں ٹرانسفر معلومات تھیں۔ ایرر کی قسم ایک تھی، مگر آس پاس کے شواہد مختلف۔
Next.js میں یہ خاص طور پر اہم ہے کیونکہ /_next/static/ کے نیچے فائلوں میں عموماً کانٹینٹ ہیش ہوتا ہے اور وہ immutable کیشنگ کے لیے بنائی جاتی ہیں۔ موجودہ Next.js کی خود میزبانی کی دستاویزات ایسے ہیش شدہ immutable اثاثوں کے لیے طویل مدتی کیش ہیڈرز بیان کرتی ہیں۔ اس لیے ChunkLoadError کے پیچھے تعیناتی کا عدم توازن، پرانا کلائنٹ، نیٹ ورک ترسیل، ریورس پراکسی، CDN، کیش، Service Worker یا واقعی غائب بلڈ فائل ہو سکتی ہے۔
میں نہیں چاہتا کہ الرٹنگ تہہ وجہ گھڑ لے۔ میں چاہتا ہوں کہ وہ جانچ کے لیے ضروری شواہد محفوظ کرے۔
میڈیا ایررز نے دوسری سمت سے یہی سبق دیا
کچھ ایونٹس میں میڈیا عنصر نے بتایا:
MEDIA_ELEMENT_ERROR: Format error
صرف یہ پیغام دیکھیں تو تقریباً کوڈیک عدم مطابقت لگتی ہے۔
مگر کچھ ایسے ایونٹس کی اضافی ترسیل جانچ نے دکھایا:
HTTP status: 410
Content-Type: text/html; charset=utf-8
failure kind: http
براؤزر نے ویڈیو مانگی تھی، مگر اسے HTML والی HTTP ایرر رسپانس ملی۔ میڈیا عنصر HTML کو ویڈیو کے طور پر ڈی کوڈ نہیں کر سکا، اس لیے بیرونی علامت “Format error” بنی۔ مفید تشخیص ترسیل کی تہہ میں تھی۔
جو تہہ مسئلہ سب سے پہلے دیکھتی ہے، ضروری نہیں کہ وہی مسئلے کی وجہ ہو۔
“کوڈیک ناکامی”، “نیٹ ورک بندش”، “کیش بگ” اور “غائب چنک” نتائج ہیں۔ ٹیلی میٹری کو پہلے مشاہدات لکھنے چاہئیں۔
میں براؤزر ناکامیوں کو پانچ جہتوں پر پرکھتا ہوں
1. ملکیت
کیا ماخذ اپنی ایپ ہے، فریم ورک/رن ٹائم ہے، بیرونی انٹیگریشن ہے یا ماحول؟
2. صارف پر اثر
کیا فعال روٹ، رینڈرنگ، توثیق، چیٹ، چیک آؤٹ یا کوئی اور بنیادی بہاؤ ٹوٹا؟ یا صرف اختیاری اشتہار، اینالیٹکس، پری لوڈ یا پری ویو ناکام ہوا جبکہ صفحہ چلتا رہا؟
3. شواہد کا معیار
کیا میرے پاس اپنے کوڈ کا اسٹیک، ریسورس URL، HTTP اسٹیٹس، بلڈ ID اور کمپوننٹ اسٹیک ہے؟ یا صرف 0:0 پر Script error.؟
4. تکرار اور پھیلاؤ
کیا یہ ایک سیشن کا ایک ایونٹ ہے، یا اسی ریلیز کے بعد مختلف صارفین، روٹس اور براؤزرز میں وہی پیٹرن دکھائی دے رہا ہے؟
5. بحالی
کیا ایپ خود بحال ہوئی؟ کیا چنک ری لوڈ طے ہوا؟ کیا فال بیک نے کام کیا؟ کیا صارف اب بھی پھنسا ہوا ہے؟
clear first-party
+ high user impact
+ strong evidence
+ multiple sessions
+ no recovery
= urgent incident
third-party
+ optional feature
+ weak evidence
+ isolated
+ user unaffected
= metric یا low priority
ایونٹس دبانے کی پالیسی محتاط ہونی چاہیے
جب شور بہت بڑھ جائے تو درجنوں ریگولر ایکسپریشن لکھ کر ہر پریشان کن چیز پھینک دینے کا دل کرتا ہے۔ یہ خطرناک ہے۔
ہر AbortError دبانے سے اصل منسوخ شدہ API درخواستیں چھپ سکتی ہیں۔ ہر Script error. پھینکنے سے براؤزر مخصوص ایسا کلسٹر چھوٹ سکتا ہے جو صرف جمع ہونے کے بعد معنی رکھتا ہے۔ ہر بیرونی ناکامی نظرانداز کرنے سے ٹوٹا ہوا ادائیگی، توثیق یا رضامندی کا فراہم کنندہ چھپ سکتا ہے۔
ALERT
→ strong incident، action required
RETAIN / AGGREGATE
→ محفوظ رکھو اور count کرو؛ cluster بنے تو alert
METRIC / SAMPLE
→ expected یا low-impact noise؛ trend اور examples محفوظ رکھو
سسٹم خاموش ہو سکتا ہے، اندھا نہیں۔
اچھا کلاسیفائر بنیادی طور پر کوڈ میں لکھی پالیسی ہے
نیچے کا کوڈ میرے پروڈکشن پروجیکٹ سے نقل نہیں کیا گیا۔ یہ اس پالیسی کی مختصر مثال ہے جس سے کاش میں شروع کرتا:
function classifyClientEvent(event) {
const owner = classifyOwner(event);
if (isExpectedMediaCancellation(event)) {
return { severity: "metric", reason: "expected-cancellation" };
}
if (owner === "first-party" && breaksActiveRoute(event)) {
return { severity: "alert", reason: "first-party-user-impact" };
}
if (isActiveFirstPartyChunkFailure(event)) {
return { severity: "alert", reason: "application-chunk" };
}
if (owner === "third-party") {
return { severity: "aggregate", reason: "integration-health" };
}
if (isOpaqueScriptError(event)) {
return { severity: "aggregate", reason: "insufficient-evidence" };
}
return { severity: "aggregate", reason: "needs-correlation" };
}
اصل مشکل breaksActiveRoute() جیسے فنکشن کے اندر ہے۔ صرف استثنا کا نام کافی نہیں؛ روٹ کا سیاق، ریسورس کی ملکیت، ایرر باؤنڈری ڈیٹا، اور کبھی کبھی پروڈکٹ کی مخصوص معلومات درکار ہوتی ہیں۔
فنگرپرنٹ کو واقعہ فالو کرنا چاہیے، پیغام کا متن نہیں
پورے پیغام کی برابری تکرار ہٹانے کی کمزور حکمت عملی ہے۔ مختصر کیے گئے اسٹیک آف سیٹس بلڈ کے ساتھ بدلتے ہیں، چنک ہیش بدلتے ہیں، URL میں متحرک شناخت کنندہ ہوتے ہیں، اور براؤزر کی عبارت مختلف ہوتی ہے۔
{
errorClass,
normalizedFirstPartyResource,
routeFamily,
clientBuild,
sessionId,
shortTimeBucket
}
پورے ایپ کریش میں اپنے کوڈ کا سب سے اوپر والا اسٹیک فریم مفید ہو سکتا ہے۔ چنک ناکامی میں معمول پر لایا گیا چنک ریسورس زیادہ مفید ہے۔ میڈیا ترسیل کے واقعے میں HTTP ناکامی کی قسم اور میڈیا روٹ براؤزر کے بیرونی ایرر پیغام سے زیادہ قیمتی ہو سکتے ہیں۔
resource.error
→ ChunkLoadError
→ framework boundary
→ recovery scheduled
تب متعلقہ ایونٹس کی ایک زنجیر چار مشاہدات والے ایک واقعے میں بدل سکتی ہے، چار الگ فوری ناکامیوں میں نہیں۔
فوری الرٹ چینل کا کام بہت محدود ہونا چاہیے
میں فوری الرٹ ان حالات کے لیے رکھوں گا: اپنی ایپ کا رن ٹائم ایرر جس کا مفید اسٹیک فعال روٹ توڑتا ہے؛ React/Next.js ایرر باؤنڈری جو حقیقی تعامل متاثر کرتی ہے؛ موجودہ روٹ کے لیے ضروری اپنی JavaScript یا CSS کا لوڈ نہ ہونا؛ کئی سیشنز یا بلڈز میں بار بار آنے والا ChunkLoadError؛ بنیادی API یا ڈیٹا ناکامی جو صارف کو روک دے؛ یا اپنے کوڈ کے واضح اصول کی خلاف ورزی، مثلاً غلط URL بننا۔
ایک اکیلا مبہم Script error.، کامیاب بحالی کے ساتھ اپنی ایپ کا ریسورس ایرر، ایسی میڈیا خرابی جس کی بنیادی تہہ ابھی معلوم نہیں، یا براؤزر مخصوص بے قاعدگی جسے پہلے گروپ کرنا ہو—ان سب کو میں محفوظ رکھوں گا مگر فوراً الرٹ نہیں دوں گا۔
اور عموماً میٹرکس یا نمونہ وار تشخیص میں بھیجوں گا: معلوم اشتہاری/اینالیٹکس ریسورس ناکامیاں؛ متوقع میڈیا AbortError؛ صرف کرالرز میں آنے والی بیرونی ناکامیاں؛ واضح آف لائن اشارے والی ناکامیاں؛ اور اختیاری پیشگی ریسورسز جو فعال روٹ کو متاثر نہیں کرتے۔
فوری الرٹ کا مطلب صارف پر ایسا اثر ہونا چاہیے جس پر کارروائی کی جا سکے، براؤزر شکایات کی خام تعداد نہیں۔
میں ایک مجموعی “ایرر کاؤنٹ” کے بجائے واقعات ناپنا چاہتا ہوں
- ہر 1,000 سیشنز پر اپنی ایپ کے واقعات؛
- بلڈ ID کے لحاظ سے متاثرہ سیشنز؛
- روٹ کے لحاظ سے ایرر باؤنڈری واقعات؛
- ریسورس اور تعیناتی کے لحاظ سے چنک ناکامیاں؛
- فراہم کنندہ کے لحاظ سے بیرونی انٹیگریشن کی ناکامی کی شرح؛
- متوقع منسوخی کی مقدار، تاکہ اچانک اضافہ پھر بھی نظر آئے؛
- بحالی کی کامیابی کی شرح؛
- منفرد واقعات کی تعداد، خام ایونٹ تعداد سے الگ۔
“ایک ایونٹ ہوا” شاذ ہی اچھا پروڈکشن الرٹ تھریش ہولڈ ہے۔ “نئے بلڈ پر اپنی ایپ کا وہی واقعہ اب کئی آزاد سیشنز کو متاثر کر رہا ہے اور بحالی بھی ناکام ہے” کہیں زیادہ مفید سگنل ہے۔
کلائنٹ مانیٹرنگ اکیلے بنیادی وجہ ثابت نہیں کر سکتی
براؤزر ٹیلی میٹری کی واضح حدیں ہیں۔
HTTP اسٹیٹس نہ ملنے کا مطلب ہو سکتا ہے کہ API نے معلومات نہیں دیں، براؤزر فیلڈ سپورٹ نہیں کرتا، کراس اوریجن پابندی لگی، درخواست منسوخ ہوئی، یا آبزرویبلٹی میں کوئی اور خلا ہے۔ Service Worker فعال ہے، اس سے ثابت نہیں ہوتا کہ اسی نے پرانا ریسورس واپس کیا۔ تعیناتی کے بعد ChunkLoadError آیا، اس سے ورژن عدم توازن ثابت نہیں ہوتا۔ online: true سے اوریجن کی رسائی بھی ثابت نہیں ہوتی۔
کلائنٹ مانیٹرنگ ممکنہ وجوہات کا دائرہ تنگ کرتی ہے۔ اصل وجہ ثابت کرنے کے لیے سرور لاگز، ریورس پراکسی لاگز، تعیناتی مینی فیسٹ، کیش کی حالت اور حقیقی دوبارہ پیدا کرنا اب بھی ضروری ہو سکتا ہے۔
میں آبزرویبلٹی کو بے حد صارف ڈیٹا جمع کرنے میں بھی نہیں بدلنا چاہتا۔ ہر فیلڈ اس لیے ہونا چاہیے کہ وہ واقعی ناکامی کی مختلف اقسام الگ کرنے میں مدد دے۔
بہتر ٹیلی میٹری کا مطلب زیادہ ٹیلی میٹری نہیں؛ زیادہ فرق کرنے والی ٹیلی میٹری ہے۔
میرا اصول اب: ایونٹس جمع کرو، واقعات کی جانچ کرو، اثر پر الرٹ کرو
شروع میں میں چاہتا تھا کہ رپورٹر صرف ایک سوال کا جواب دے: “کچھ ٹوٹا؟” پروڈکشن میں یہ سوال اتنا وسیع ہے کہ بے فائدہ ہو جاتا ہے۔ کہیں کوئی کرالر اینالیٹکس تک نہیں پہنچتا، رازداری کا آلہ اشتہار روکتا ہے، میڈیا Promise جان بوجھ کر منسوخ ہوتی ہے، صارف نیٹ ورک کھو دیتا ہے، یا بیرونی SDK غلط برتاؤ کرتا ہے۔
کیا یہ ہمارا ہے؟
کیا user نے functionality کھوئی؟
Evidence کتنا strong ہے؟
کیا repeat ہو رہا ہے؟
کیا application recover ہوئی؟
یہ کئی events ہیں یا ایک incident؟
جب مانیٹرنگ کو ان زیادہ مخصوص سوالوں کے گرد بنایا، سرخ پیغامات کا سیلاب شور سے انجینئرنگ آلے میں بدل گیا۔
براؤزر ایرر ایک مشاہدہ ہے۔ واقعہ صارف پر اثر کی باہم مربوط تشریح ہے۔ الرٹ یہ فیصلہ ہے کہ اب انسان کو کارروائی کرنی چاہیے۔
میں ان تینوں کو دوبارہ ایک ہی چیز نہیں سمجھنا چاہتا۔