سی اجرای موفق در ماه، صفر پیام فرستادهشده، صفر هشدار. این کارنامهی ماه ششم یک ورکفلوی «یادآوری سبد رهاشده» است که هر شب سر ساعت اجرا میشد و داشبوردش همیشه سبز بود. صاحب فروشگاه وقتی فهمید که دید خرید برگشتیاش صفر شده است.
این ماجرا فرضی است و عددهایش برای نشان دادن روش ساخته شدهاند، ولی شکلش در اتوماسیون آشناست. مدیریت خطا در n8n معمولا یعنی «وقتی گرهای قرمز شد چه کنیم». بدترین خرابیها اما هیچ گرهای را قرمز نمیکنند.
کارنامهی ماه اول و ماه ششم
| سنجه | ماه اول | ماه ششم |
|---|---|---|
| اجرای موفق ورکفلو در ماه | ۳۰ | ۳۰ |
| یادآوری فرستادهشده | ۴۸۰ | ۰ |
| خرید برگشتی | ۲۹ | ۰ |
| هشدار دریافتشده | ۰ | ۰ |
ردیف اول یک چیز را همان اول از فهرست مظنونها بیرون میگذارد: زمانبندی سالم است. ورکفلو هر شب شروع شده. پس مشکل بعد از تریگر است؛ یا دادهای پیدا نمیشود، یا گرهی ارسال کار نمیکند.
ردگیری: کجا صفر شد
قدم بعد کاری است که در این شش هفته هیچکس انجام نداده بود: باز کردن لاگ یک اجرا و شمردن خروجی هر گره. گرهی «واکشی سبدهای رهاشده» صفر آیتم برگردانده بود. در n8n وقتی گرهای صفر آیتم بدهد، گرههای بعدی اصلا اجرا نمیشوند و ورکفلو بدون هیچ خطایی «موفق» تمام میشود.
چرا صفر؟ کوئری سبدهایی را میخواست که بیست و چهار تا چهل و هشت ساعت از رها شدنشان گذشته بود، و تاریخ را با ساعت سرور میساخت که به وقت جهانی تنظیم بود، نه به وقت تهران. با اختلاف سه ساعت و نیم، دو بازه هنوز روی هم میافتادند و در ماههای اول همهچیز درست کار میکرد. بعد سرویس فروشگاه شکل نوشتن تاریخ را عوض کرد و مقایسه بیصدا هیچ نتیجهای برنگرداند.
حساب ضرر هم ساده است. ماه اول بیست و نه خرید برگشتی در سی روز داشت. چهل و یک روز خاموشی با همان آهنگ یعنی حدود چهل خرید از دسترفته. و مهمتر از عدد این است که هیچکس نفهمید، چون همهی داشبوردها «سی اجرای موفق» را سبز نشان میدادند.
«اجرا شد» با «کار کرد» یکی نیست.
سه جنس خطا و واکنش هر کدام
| جنس | نمونه | واکنش درست |
|---|---|---|
| گذرا | قطعی لحظهای شبکه، خطای ۵۰۳، تمام شدن مهلت | تلاش دوباره با فاصلهی فزاینده |
| دائمی | کلید نامعتبر (۴۰۱)، شمارهی خراب، ۴۰۴ | تلاش دوباره بیفایده است؛ ثبت کن و خبر بده |
| منطقی | همهچیز موفق، نتیجه غلط | فقط با بررسی خود نتیجه گرفته میشود |
ماجرای سبد رهاشده از جنس سوم بود و جنس سوم بدترین است، چون هیچ استثنایی پرتاب نمیشود و هیچ لاگ قرمزی نداری. فقط نتیجهای داری که کسی نگاهش نکرده.
جنس دوم هم دام خودش را دارد. کلید اشتباه با تلاش دوباره درست نمیشود؛ فقط سه بار همان خطا را میگیری و سه برابر منتظر میمانی. و اگر گره عوارض جانبی داشته باشد، مثل پیامک یا پرداخت، تلاش دوباره پول هم خرج میکند.
Continue On Fail؛ کلیدی که هشدار را خاموش میکند
تنظیمی هست که برای «وسط راه نایستادن» روشن میشود: Continue On Fail. فرض کن روی گرهی ارسال پیامک روشنش کردهای و امروز آن گره شکست خورد. ورکفلوی خطایی که ساختهای اجرا میشود؟ نه. ورکفلوی خطا فقط وقتی اجرا میشود که کل ورکفلو با خطا تمام شود، و با این تنظیم، ورکفلو موفق تمام میشود.
این رایجترین راهی است که یک اتوماسیون ماهها بیصدا خراب میماند. معنای واقعی این کلید این است: «مسئولیت بررسی این گره را خودم برعهده میگیرم.» پس اگر روشنش کردی، بلافاصله بعدش یک گرهی IF بگذار که نتیجه را بررسی کند و در شاخهی خطا صریح هشدار بفرستد. اگر قرار نیست بررسی کنی، روشنش نکن. ورکفلویی که وسط راه میایستد و خبر میدهد، از ورکفلویی که تا آخر میرود و ساکت میماند بهتر است.
چهار لایهی محافظت، به ترتیب نصب
- تلاش دوباره روی گرههای HTTP: سه بار با فاصلهی فزاینده. پیشفرض خاموش است. روی گرههای پرهزینه مثل پیامک و پرداخت با احتیاط روشنش کن.
- مهلت زمانی: بدون آن، یک سرویس کند میتواند ورکفلو را مدتها معطل نگه دارد و صف را ببندد.
- یک ورکفلوی خطای مشترک: با Error Trigger ساخته میشود و در تنظیمات هر ورکفلو انتخابش میکنی. یک بار ساخته میشود و همه از آن استفاده میکنند.
- هشداری که چیزی میگوید: نه فقط «شکست»؛ نام ورکفلو، گرهی آخری که اجرا شد، زمان به وقت تهران، متن خطا و لینک همان اجرا.
در لایهی چهارم ترتیب خطها هم مهم است. نام ورکفلو و نام گره باید اول بیایند، چون در اعلان گوشی معمولا فقط دو خط اول دیده میشود. و این هشدار را ماهی یک بار عمدا امتحان کن؛ هشداری که خودش خراب شده از نبودنش بدتر است، چون به سکوتش اعتماد میکنی.
گاردی که صفر را به خطا تبدیل میکند
هیچکدام از چهار لایه ماجرای سبد رهاشده را نمیگرفت. راهحلش ساختاری است: برای هر ورکفلو بپرس «چه عددی باید غیرصفر باشد؟» و همان را زیر نظر بگیر، نه فقط موفق بودن اجرا را.
در ورکفلوهایی که باید چیزی پیدا کنند، بعد از گرهی واکشی یک IF بگذار؛ اگر تعداد آیتمها صفر بود، ورکفلو را به گرهی Stop and Error بفرست. عمدا خطا انداختن اینجا کار درستی است، چون ورکفلوی خطا را بیدار میکند.
یک استثنا را هم در نظر بگیر. بعضی ورکفلوها واقعا ممکن است روزی صفر آیتم داشته باشند و طبیعی باشد؛ روزی که هیچ سبدی رها نشده. برای آنها گارد درست «صفر در چند روز پشت سر هم» است، نه «صفر در یک اجرا».
دو بار اجرا، یک پیامک
خطا فقط ساکت نمیماند؛ گاهی دو بار کار میکند. سرویسی کند جواب میدهد، مهلت تمام میشود، گره دوباره تلاش میکند، و پیامکی که بار اول هم رفته بود دوباره میرود. تمام شدن مهلت یعنی جواب نگرفتی، نه اینکه کار انجام نشد.
راهش یک جدول کوچک در همان پایگاه دادهی n8n است با یک ستون کلید یکتا. پیش از گرهی پیامک، کلید آن رویداد (مثلا شناسهی لید، یا شماره بهاضافهی تاریخ روز) درج میشود، طوری که اگر تکراری بود هیچ ردیفی برنگردد. اگر ردیفی برنگشت، یعنی قبلا رفته و نباید دوباره برود.
چرا این کار در پایگاه داده و نه با «اول بخوان، بعد بنویس» در یک IF؟ چون میان خواندن و نوشتن، اجرای دوم میتواند از راه برسد و هر دو خیال کنند اولیناند. کلید یکتا این را جایی حل میکند که واقعا یکجا و تجزیهناپذیر انجام میشود.
هشداری که همه بعد از چند هفته نادیده میگیرند
یک اتفاق قابل پیشبینی هست: هشدارها زیاد میشوند، بیشترشان بیاهمیتاند، و تو یاد میگیری از رویشان رد شوی. از آن روز عملا هشدار نداری. سه قاعده جلویش را میگیرد:
- هر هشدار باید یک اقدام داشته باشد. اگر خواندنش کاری از تو نمیخواهد، هشدار نیست؛ لاگ است و جایش جای دیگری است.
- خطای گذرا نباید فورا خبر بدهد. بگذار تلاش دوباره کارش را بکند و فقط وقتی هر سه تلاش شکست خورد خبر بده.
- تغییر وضعیت را خبر بده، نه خود وضعیت را. «قطع شد» یک بار و «وصل شد» یک بار، نه هر پانزده دقیقه «هنوز قطع است».
قاعدهی سوم از یک تجربهی واقعی آمده: سیستمی که در هر دور بررسی هشدار میفرستاد، در چند ساعت دهها پیام یکسان فرستاد. راهحل کم کردن فاصله یا متنوع کردن متن نبود؛ یک وضعیت ماندگار در پایگاه داده بود که فقط در لحظهی تغییر خبر میدهد.
سه خرابی که عمدا میسازی
هدف این تمرین این نیست که ورکفلوی تو هیچوقت نشکند. این است که وقتی شکست، بفهمی. ورکفلوی هشدار را بساز، به ورکفلوی اصلیات وصل کن و سه بار عمدا خرابش کن.
کلید خراب
کلید سرویس را یک کاراکتر عوض کن و اجرا کن. باید هشدار بیاید و نام گره در آن باشد. بعد روی همان گره Continue On Fail را روشن کن و دوباره اجرا کن؛ ببین که این بار هشداری نمیآید. دیدن این سکوت با چشم خودت از هر توضیحی ماندگارتر است.
صفر آیتم
فیلتر کوئری را طوری عوض کن که هیچچیز از آن رد نشود. اول ببین هیچ هشداری نمیآید، بعد گارد صفر را بگذار و دوباره امتحان کن. هر دو حالت را باید دیده باشی.
درخواست تکراری
همان درخواست را دو بار پشت سر هم بفرست. با کلید یکتا باید فقط یک اثر بماند.
آخر سر برای ورکفلوی خودت یک جمله بنویس: «عددی که باید غیرصفر باشد این است.» اگر نمیتوانی آن جمله را بنویسی، هنوز نمیدانی ورکفلویت کی کار کرده است.
مرز این روش
این الگوها خرابی را دیدنی میکنند، نه ناممکن. هیچ اتوماسیونی بینقص نیست؛ فرق کار حرفهای با کار آماتور این است که اولی میفهمد کی شکست. اگر میخواهی مدیریت خطا در n8n را کنار بقیهی پایهها (شکل داده، کلیدها، آزمون پیش از اجرای واقعی و اتصال به سرویسهای ایرانی) روی یک پروژهی واقعی تمرین کنی، جزئیات این دوره را ببین.