FormatImportCycleError formats an import cycle error with a delightful multiline indented display
(err *ImportCycleError)
| 36 | |
| 37 | // FormatImportCycleError formats an import cycle error with a delightful multiline indented display |
| 38 | func FormatImportCycleError(err *ImportCycleError) error { |
| 39 | importErrorLog.Printf("Formatting import cycle error: chain=%v, workflow=%s", err.Chain, err.WorkflowFile) |
| 40 | |
| 41 | if len(err.Chain) < 2 { |
| 42 | return errors.New("circular import detected (invalid chain)") |
| 43 | } |
| 44 | |
| 45 | // Build a multiline, indented representation of the import chain |
| 46 | var messageBuilder strings.Builder |
| 47 | messageBuilder.WriteString("Import cycle detected\n\n") |
| 48 | messageBuilder.WriteString("The following import chain creates a circular dependency:\n\n") |
| 49 | |
| 50 | // Show each step in the chain with indentation to emphasize the flow |
| 51 | for i, file := range err.Chain { |
| 52 | indent := strings.Repeat(" ", i) |
| 53 | if i == 0 { |
| 54 | fmt.Fprintf(&messageBuilder, "%s%s (starting point)\n", indent, file) |
| 55 | } else if i == len(err.Chain)-1 { |
| 56 | // Last item is the back-edge - highlight it |
| 57 | fmt.Fprintf(&messageBuilder, "%s↳ %s ⚠️ cycles back to %s\n", indent, file, err.Chain[0]) |
| 58 | } else { |
| 59 | fmt.Fprintf(&messageBuilder, "%s↳ imports %s\n", indent, file) |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | messageBuilder.WriteString("\nTo fix this issue:\n") |
| 64 | messageBuilder.WriteString("1. Review the import dependencies in the files listed above\n") |
| 65 | messageBuilder.WriteString("2. Remove one of the imports to break the cycle\n") |
| 66 | messageBuilder.WriteString("3. Consider restructuring your workflow imports to avoid circular dependencies\n") |
| 67 | |
| 68 | return &FormattedParserError{formatted: messageBuilder.String(), cause: err} |
| 69 | } |
| 70 | |
| 71 | // FormattedParserError is a sentinel error type returned by FormatImportError (and similar |
| 72 | // parser-level formatters) to signal that the error message is already console-formatted |