( blockId: string, dag: BlockDependencyDag, lintResult: LintResult, blockMap: Map<string, BlockInfo> )
| 758 | * Diagnose why a block might have failed by analyzing its dependencies. |
| 759 | */ |
| 760 | export function diagnoseBlockFailure( |
| 761 | blockId: string, |
| 762 | dag: BlockDependencyDag, |
| 763 | lintResult: LintResult, |
| 764 | blockMap: Map<string, BlockInfo> |
| 765 | ): FailureDiagnosis { |
| 766 | const node = dag.nodes.find(n => n.id === blockId) |
| 767 | const info = blockMap.get(blockId) |
| 768 | |
| 769 | // Find upstream blocks (blocks that this block depends on) |
| 770 | const upstream: UpstreamBlock[] = [] |
| 771 | const incomingEdges = dag.edges.filter(e => e.to === blockId) |
| 772 | |
| 773 | for (const edge of incomingEdges) { |
| 774 | const sourceNode = dag.nodes.find(n => n.id === edge.from) |
| 775 | const sourceInfo = blockMap.get(edge.from) |
| 776 | if (sourceNode && sourceInfo) { |
| 777 | upstream.push({ |
| 778 | id: edge.from, |
| 779 | label: sourceInfo.label, |
| 780 | variables: sourceNode.outputVariables.filter(v => node?.inputVariables.includes(v) ?? false), |
| 781 | }) |
| 782 | } |
| 783 | } |
| 784 | |
| 785 | // Find lint issues related to this block |
| 786 | const relatedIssues = lintResult.issues.filter(issue => issue.blockId === blockId) |
| 787 | |
| 788 | return { |
| 789 | blockId, |
| 790 | blockLabel: info?.label ?? blockId, |
| 791 | upstream, |
| 792 | relatedIssues, |
| 793 | usedVariables: node?.inputVariables ?? [], |
| 794 | } |
| 795 | } |
| 796 | |
| 797 | /** |
| 798 | * Build a block map from a DeepnoteFile for use with diagnosis functions. |
no outgoing calls
no test coverage detected