FormatImportError formats an import error as a compilation error with source location
(err *ImportError, yamlContent string)
| 93 | |
| 94 | // FormatImportError formats an import error as a compilation error with source location |
| 95 | func FormatImportError(err *ImportError, yamlContent string) error { |
| 96 | importErrorLog.Printf("Formatting import error: path=%s, file=%s, line=%d", err.ImportPath, err.FilePath, err.Line) |
| 97 | |
| 98 | lines := strings.Split(yamlContent, "\n") |
| 99 | |
| 100 | // Create context lines around the error |
| 101 | var context []string |
| 102 | startLine := max(1, err.Line-2) |
| 103 | endLine := min(len(lines), err.Line+2) |
| 104 | |
| 105 | for i := startLine; i <= endLine; i++ { |
| 106 | if i-1 < len(lines) { |
| 107 | context = append(context, lines[i-1]) |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // Determine the error message based on the cause |
| 112 | message := "failed to resolve import" |
| 113 | if err.Cause != nil { |
| 114 | causeMsg := err.Cause.Error() |
| 115 | if strings.Contains(causeMsg, "file not found") { |
| 116 | message = "import file not found" |
| 117 | } else if strings.Contains(causeMsg, "failed to download") { |
| 118 | message = "failed to download import file" |
| 119 | } else if strings.Contains(causeMsg, "failed to resolve ref") { |
| 120 | message = "failed to resolve import reference" |
| 121 | } else if strings.Contains(causeMsg, "invalid workflowspec") { |
| 122 | message = "invalid import specification" |
| 123 | } else { |
| 124 | message = causeMsg |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | hint := buildImportErrorHint(message, err.ImportPath) |
| 129 | compilerErr := console.CompilerError{ |
| 130 | Position: console.ErrorPosition{ |
| 131 | File: err.FilePath, |
| 132 | Line: err.Line, |
| 133 | Column: err.Column, |
| 134 | }, |
| 135 | Type: "error", |
| 136 | Message: message, |
| 137 | Context: context, |
| 138 | Hint: hint, |
| 139 | } |
| 140 | |
| 141 | formattedErr := console.FormatError(compilerErr) |
| 142 | // Return a FormattedParserError so callers can detect that this error is already |
| 143 | // console-formatted and must not be re-wrapped with additional location context. |
| 144 | return &FormattedParserError{formatted: formattedErr, cause: err.Cause} |
| 145 | } |
| 146 | |
| 147 | // buildImportErrorHint returns a tailored fix hint for an import error based on its message and path. |
| 148 | func buildImportErrorHint(message, importPath string) string { |