Repository navigation
Trace a provider failure out of a sub-workflow child run - #2132
Merged
Merged
Conversation
A provider failure inside a flow.subworkflow child run that ended the parent was recorded on the child's own ledger and nowhere the parent's page could find it. The parent's node failed with the sentence "Sub-workflow run failed: Node 'x' failed." and nothing else, so the parent's run page said "Node 'sub' failed." with no card, no credential and no repair, while the child's page showed all three. When a child run ends failed, the completion path that resumes its parent now reads the child's decisive failure with the reader the child's own run page asks (IRunFailureReader, so the two can never name different failures) and puts it on the resume payload together with the child run, the node that ended it and when the child recorded it. That path is the one the engine's completion hook and the reconciler's stranded-parent backstop both run, so a parent recovered after a lost hook learns the same thing. The sub-workflow node still fails with its own sentence, untouched, and the failure rides beside it on the new NodeResult.CarriedFailure; the engine writes it on the parent's node.failed record exactly as it writes one read off an exception, and a container the node sits in (a map or loop) carries it as it carries any cell's. The parent's remedy is the child's remedy: same code, credential, repositories, buttons and resolution, computed for the caller's standing in the parent's team, which is the child's by construction. The failure's new Origin names the run it happened in, and the remedy gains an additive Origin (run, workflow, node) that is read live under the asker's team: a run that is not the team's, or is gone, is never named and does not change the remedy. A failure that names no repository is traced through the child's launch scope, as the child's page does, not the parent's. Whether the credential has been fixed since is measured from when the child recorded the failure, not from the parent's own record: a parent waiting on several sub-workflows is resumed only when the slowest has finished, so its record can be far later than the failure, and a token replaced from the child's page in between would read as older than the failure on the parent's. A failure that kept no time is judged from the record that carries it, as before. The cause leads with a sentence naming the sub-workflow and run, and the card shows it as a link that opens that run. Re-run is still the page's own: it replays the parent, which starts a fresh child. A failure that travelled through nested sub-workflows keeps the origin it was first stamped with, so every level names the deepest run that met it, independent of the order the levels finish. A retried node carries the last attempt's child. A child that failed on anything else, handled the failure with an error edge, handled it and then failed on something else, or was cancelled carries nothing, so the parent keeps the sentence it always had. Reading the failure is a courtesy to the page: if the read fails the parent is still resumed. Additive throughout: no migration. The failure, the resume payload and the remedy each gain an optional member that older readers ignore, and rows and payloads written before read exactly as they did.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
flow.subworkflowchild run that ends the parent now reaches the parent's run page: the completion path that resumes the parent reads the child's decisive failure with the sameIRunFailureReaderthe child's own page asks, carries it on the resume payload, and the sub-workflow node fails with it beside its unchanged sentence (NodeResult.CarriedFailure). The parent'snode.failed, and a map/loop container above it, record it with aFailureOriginnaming the deepest child run that met it, the node that ended that run, and when that run recorded it.Origin(run, workflow, node) read live under the asker's team: a run that is not the team's, or is gone, is never named and changes nothing else. The cause leads with "This failed in the sub-workflow ... (run ...)", the card links to that run, and Re-run still replays the parent, which starts a fresh child.FailureOrigin.At), not from the parent's own record. A parent waiting on several sub-workflows is resumed only when the slowest has finished, so its record can be far later than the failure; judged from it, a token replaced from the child's page in between read as older than the failure on the parent's page while the child's page said it was fixed. A failure that kept no time is judged from the carrying record's, as before.Test plan
git.list_prsagainst a dead GitLab credential with an owner, at top level, in a map, in a loop and three levels deep; a fan-out of two children where the token is replaced between the child's failure and the slow sibling's end (parent and child pages agree it is fixed); a carried failure judged from its kept time or, with none, from its record's; non-provider child failure, handled failure, handled-then-failed and cancelled child yield no remedy; an origin that is not the team's is never named; stranded-parent backstop inStuckRunReconcilerFlowTests; 505 passed in the related classesProviderRemedyCard.test.tsxandRunRemedyCard.test.tsx(unchanged by the latest revision)