Riešenie problémov
Začnite cez php artisan workflows:doctor (v CI pridajte --json, --strict zlyhá aj pri varovaniach), potom workflows:list --status=failed a workflows:show <ulid> pre cestu, záznam krokov, čakania a najbližšiu eskaláciu jednej inštancie.
Zistenia doctor
Úrovne sú enum DoctorLevel (ok, warn, fail):
| Kontrola | Úroveň | Zistenie | Riešenie |
|---|---|---|---|
| key types | ok / fail | Kľúč registrovaného subjektu nezodpovedá subject_key_type. | Pred migráciou nastavte workflows.subject_key_type (alebo key_type) na typ kľúča modelu. |
| owner key type | fail | Kľúč modelu tímu nezodpovedá owner_key_type. | Nastavte workflows.owner_key_type na uuid / ulid. |
| queue | warn | Front je vypnutý alebo je spojenie sync. | Lokálne v poriadku; v produkcii zapnite front so skutočným spojením. |
| queue timeout | fail | retry_after ≤ timeout jobu kroku. | Zvýšte retry_after spojenia nad engine.lease − 30 s alebo znížte engine.lease. |
| pcntl | warn | Worker nedokáže vynútiť timeout jobu. | Na workeroch nainštalujte rozšírenie pcntl. |
| cache | warn | Predvolené úložisko cache je array alebo file. | Pre onOneServer() použite úložisko zdieľané všetkými servermi (redis, database, memcached, dynamodb). |
| wake | warn | workflows:wake ešte nebežal alebo naposledy bežal pred viac ako piatimi minútami. | Naplánujte ho každú minútu s withoutOverlapping()->onOneServer() a spustite plánovač. |
| step types | ok / fail | Katalóg sa nenačíta alebo aktívna verzia používa typ kroku, ktorý už nie je registrovaný. | Opravte alebo odstráňte uvedenú triedu, typ znova zaregistrujte alebo publikujte verziu bez neho. |
| config schema | fail | configSchema() vlastného typu používa kľúčové slovo, ktoré validátor nepodporuje. | Napíšte ju cez ConfigSchema. |
| adapter | fail | Aktívna definícia používa typ kroku, ktorého balík chýba. | composer require roundly-consulting/<package> alebo publikujte verziu bez kroku. |
| calendar | fail | Predvolený kalendár aktívnej definície chýba. | Zaregistrujte ho alebo vytvorte kalendár otváracích hodín pre vlastníka. |
| opening hours | fail | Aktívna definícia používa kalendár opening_hours:, ale model vlastníka nepoužíva HasOpeningHours. | Pridajte implements OpeningHoursOwner + use HasOpeningHours do modelu vlastníka (pri teams: do vymeneného modelu tímu). |
| condition waits | warn | Aktívna verzia čaká na podmienku typu subjektu, ktorého model nepoužíva HasWorkflows. | Pridajte trait alebo počítajte s tým, že sa podmienka overí len pri pravidelnej kontrole. |
| events | fail / warn | Namapovaná trieda neexistuje alebo '*' nie je WorkflowEvent (fail); namapovaná udalosť nemá idempotentný kľúč, trieda je namapovaná dvakrát alebo mapovanie pre definíciu on_behalf_of nemá používateľa (warn). | Opravte mapovanie; pridajte idempotency_key; ponechajte jedno mapovanie; namapujte user alebo spúšťajte ako system. |
| webhooks | ok / fail | Route je zapnutá bez verify_middleware (ostáva nezaregistrovaná). | Nastavte workflows.webhooks.verify_middleware, napr. ['sentinel.signed:<profile>']. |
| stuck | warn | Bežiace inštancie, ktoré dlhšie než engine.lease nemajú nič vo fronte, nebežia ani nečakajú. | workflows:show <ulid>; zvyčajne stratený job, ktorý wake znova odošle po engine.requeue_after; inak workflows:retry alebo workflows:cancel. |
| wake backlog | warn | Čakania alebo eskalácie splatné pred viac ako piatimi minútami. | Skontrolujte plánovač a zvýšte wake.batch. |
| bridges / failures | ok | Nainštalované prepojenia; koľko inštancií zlyhalo za posledných 24 hodín. | — |
Kódy zlyhania
WorkflowInstance::failure() a StepRun::error() vrátia hodnotu FailureCode (kód v tvare code:detail podľa prefixu; detail prečíta FailureCode::detail()) alebo pri vlastnom kóde hostiteľského kroku reťazec. „Pomôže opakovanie“ znamená, že workflows:retry (alebo instances()->retry()) môže uspieť, keď príčina zmizne — FailureCode::retryable(). Opakovanie pokračuje tam, kde krok zlyhal: zlyhaný handle() sa spustí znova a zlyhaný resume() sa znova obnoví so signálom, ktorý dostal (payload udalosti, rozhodnutie, časový limit), takže udalosť, ktorá už prišla, netreba posielať znova. Každý kód má anglickú aj slovenskú správu (FailureCode::message()).
| Kód | Zapíše sa, keď | Pomôže opakovanie |
|---|---|---|
adapter_missing | Krok potrebuje balík, ktorý nie je nainštalovaný (approval, notify, transition, spúšťač s formulárom). | áno, po jeho inštalácii |
approval_cancelled | Kolo schvaľovania bolo zrušené mimo workflowu. | nie |
approval_closed | Kolo schvaľovania už bolo uzavreté, keď s ním krok pracoval. | nie |
approval_missing | Kolo schvaľovania už neexistuje. | nie |
authorization_denied | Autorizačný hook krok odmietol (policy, abilities, systémový aktér). | áno, po udelení oprávnenia |
calendar_missing | Pracovný kalendár, ktorý krok potrebuje, vlastníkovi chýba. | áno, po jeho vytvorení |
calendar_never_open | Kalendár nemá v hľadanom okne žiadny otvorený čas. | nie (opravte kalendár, potom zrušte a spustite znova) |
child_not_started | Dieťa start_workflow sa nepodarilo spustiť (vyradené, neaktívne, nepokryté vstupy) alebo ho odmietol limit spustení (automaticky sa opakuje s odstupom). | áno, po oprave definície dieťaťa (alebo keď sa v limite uvoľní miesto) |
delay_field_empty | Oneskorenie s until_field našlo prázdne pole. | áno, po vyplnení poľa |
ended_by_graph | Uzol end so status: failed. | nie |
exception | Handler vyhodil neznámu výnimku (správa sa ukladá pre operátorov, nikdy sa nezobrazí). | áno |
field_write_refused | set_field mieril na stavový stĺpec lifecycle. | nie |
idempotency_conflict | Lifecycle dostal rovnaký idempotentný kľúč pre iný prechod. | nie |
invalid_approval_request | Approvals požiadavku odmietol (konfigurácia). | nie |
invalid_output | Handler vrátil výstup, ktorý nie je čistý JSON alebo prekračuje steps_output.max_bytes. | nie (opravte handler) |
invalid_value | set_field dostal za behu hodnotu nesprávneho typu. | nie |
lease_expired | Prevzatý krok prekročil svoj lease (spadnutý alebo pomalý worker). | áno (opakuje sa automaticky) |
missing_edge | Nasledujúci uzol neexistuje. | nie |
missing_outcome_edge | Krok skončil výsledkom, ktorý nemá hranu. | nie (publikujte verziu s hranou) |
missing_trigger | Verzia nemá spúšťač. | nie |
nesting_depth_exceeded | start_workflow sa vnoril hlbšie než limits.max_depth. | nie |
no_approvers | Schvaľovatelia sa vyhodnotili na nikoho. | áno, po oprave strán |
no_result | Handler nevrátil nič. | nie (opravte handler) |
notification_refused:<code> | Notifications notifikáciu natrvalo odmietol. | nie |
owner_mismatch | Subjekt už nepatrí vlastníkovi workflowu. | áno, ak sa vráti späť |
resume_unsupported | Signál dorazil k typu kroku, ktorý sa nedá obnoviť. | nie |
roles_unavailable | Strana typu role bez vyhodnocovania rolí (teams alebo parties.roles). | áno, po jeho nastavení |
start_rate_exceeded | Definícia sa za minútu spustila viac než limits.max_starts_per_minute krát. | nie — nebežal žiadny krok; spustenie pošlite znova (kľúč ostal voľný) |
step_limit_exceeded | Inštancia vykonala viac než limits.max_steps krokov. | nie |
step_missing | Čakajúci krok eskalácie už neexistuje. | nie |
subject_missing | Subjekt bol zmazaný alebo nie je v kontexte vlastníka viditeľný. | áno, ak sa obnoví |
transition_conflict | K subjektu sa skôr dostala iná zmena (opakuje sa automaticky). | áno |
transition_denied:<code> | Strážca lifecycle prechod odmietol (automaticky sa opakuje, len ak to lifecycle povolí). | nie — iba ak sa zmení to, čo strážca kontroluje |
transition_unusable | Prechod sa na tento subjekt nedá použiť. | nie |
unknown_approval_preset | Preset schvaľovania neexistuje. | nie |
unknown_escalation_action | Typ eskalačnej akcie nie je dostupný. | nie |
unknown_step_type | Typ kroku uzla nie je registrovaný (alebo uzol zmizol). | áno, po jeho registrácii |
version_missing | Verzia inštancie už neexistuje. | nie |
worker_timeout | Worker frontu job ukončil. | áno (opakuje sa automaticky) |
Výnimky balíka, ktoré krok premení na zlyhanie (napríklad odmietnuté spustenie dieťaťa), si ponechajú vlastné kódy chýb — pozri Výnimky.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.