Skip to content

Commit 262e711

Browse files
authored
cli: standardize error wrapping with %w (#3040) (#3094)
Signed-off-by: mohamedfawas <[email protected]>
1 parent 414dcff commit 262e711

File tree

43 files changed

+229
-229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+229
-229
lines changed

cmd/thv-operator/api/v1alpha1/virtualmcpcompositetooldefinition_webhook.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func (r *VirtualMCPCompositeToolDefinition) validateParameters() error {
109109
// Unmarshal to validate structure
110110
var params map[string]interface{}
111111
if err := json.Unmarshal(r.Spec.Parameters.Raw, &params); err != nil {
112-
return fmt.Errorf("spec.parameters: invalid JSON: %v", err)
112+
return fmt.Errorf("spec.parameters: invalid JSON: %w", err)
113113
}
114114

115115
// Validate that it has "type" field
@@ -131,7 +131,7 @@ func (r *VirtualMCPCompositeToolDefinition) validateParameters() error {
131131

132132
// Validate using JSON Schema validator
133133
if err := validateJSONSchema(r.Spec.Parameters.Raw); err != nil {
134-
return fmt.Errorf("spec.parameters: invalid JSON Schema: %v", err)
134+
return fmt.Errorf("spec.parameters: invalid JSON Schema: %w", err)
135135
}
136136

137137
return nil
@@ -194,7 +194,7 @@ func (r *VirtualMCPCompositeToolDefinition) validateStep(index int, step Workflo
194194

195195
if step.Timeout != "" {
196196
if err := validateDuration(step.Timeout); err != nil {
197-
return fmt.Errorf("spec.steps[%d].timeout: %v", index, err)
197+
return fmt.Errorf("spec.steps[%d].timeout: %w", index, err)
198198
}
199199
}
200200

@@ -245,34 +245,34 @@ func validateWorkflowStepTemplates(pathPrefix string, index int, step WorkflowSt
245245
if step.Arguments != nil && len(step.Arguments.Raw) > 0 {
246246
var args map[string]any
247247
if err := json.Unmarshal(step.Arguments.Raw, &args); err != nil {
248-
return fmt.Errorf("%s[%d].arguments: invalid JSON: %v", pathPrefix, index, err)
248+
return fmt.Errorf("%s[%d].arguments: invalid JSON: %w", pathPrefix, index, err)
249249
}
250250
for argName, argValue := range args {
251251
// Only validate template syntax for string values
252252
if strValue, ok := argValue.(string); ok {
253253
if err := validateTemplate(strValue); err != nil {
254-
return fmt.Errorf("%s[%d].arguments[%s]: invalid template: %v", pathPrefix, index, argName, err)
254+
return fmt.Errorf("%s[%d].arguments[%s]: invalid template: %w", pathPrefix, index, argName, err)
255255
}
256256
}
257257
}
258258
}
259259

260260
if step.Condition != "" {
261261
if err := validateTemplate(step.Condition); err != nil {
262-
return fmt.Errorf("%s[%d].condition: invalid template: %v", pathPrefix, index, err)
262+
return fmt.Errorf("%s[%d].condition: invalid template: %w", pathPrefix, index, err)
263263
}
264264
}
265265

266266
if step.Message != "" {
267267
if err := validateTemplate(step.Message); err != nil {
268-
return fmt.Errorf("%s[%d].message: invalid template: %v", pathPrefix, index, err)
268+
return fmt.Errorf("%s[%d].message: invalid template: %w", pathPrefix, index, err)
269269
}
270270
}
271271

272272
// Validate JSON Schema for elicitation steps
273273
if step.Schema != nil {
274274
if err := validateJSONSchema(step.Schema.Raw); err != nil {
275-
return fmt.Errorf("%s[%d].schema: invalid JSON Schema: %v", pathPrefix, index, err)
275+
return fmt.Errorf("%s[%d].schema: invalid JSON Schema: %w", pathPrefix, index, err)
276276
}
277277
}
278278

@@ -360,7 +360,7 @@ func validateTemplate(tmpl string) error {
360360
// Try to parse as Go template
361361
_, err := template.New("validation").Parse(tmpl)
362362
if err != nil {
363-
return fmt.Errorf("invalid template syntax: %v", err)
363+
return fmt.Errorf("invalid template syntax: %w", err)
364364
}
365365
return nil
366366
}
@@ -374,7 +374,7 @@ func validateJSONSchema(schemaBytes []byte) error {
374374
// Parse the schema JSON to verify it's valid JSON
375375
var schemaDoc interface{}
376376
if err := json.Unmarshal(schemaBytes, &schemaDoc); err != nil {
377-
return fmt.Errorf("failed to parse JSON: %v", err)
377+
return fmt.Errorf("failed to parse JSON: %w", err)
378378
}
379379

380380
// Use gojsonschema to validate the schema by attempting to use it as a schema
@@ -388,7 +388,7 @@ func validateJSONSchema(schemaBytes []byte) error {
388388
_, err := gojsonschema.Validate(schemaLoader, documentLoader)
389389
if err != nil {
390390
// Check if error is about the schema itself (not validation failure)
391-
return fmt.Errorf("invalid JSON Schema: %v", err)
391+
return fmt.Errorf("invalid JSON Schema: %w", err)
392392
}
393393

394394
return nil

cmd/thv-operator/pkg/controllerutil/authz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func AddAuthzConfigOptions(
235235
if err := yaml.Unmarshal([]byte(raw), &cfg); err != nil {
236236
// Fallback to JSON explicitly for clearer error paths
237237
if err2 := json.Unmarshal([]byte(raw), &cfg); err2 != nil {
238-
return fmt.Errorf("failed to parse authz config from ConfigMap %s/%s key %q: %v; json fallback error: %v",
238+
return fmt.Errorf("failed to parse authz config from ConfigMap %s/%s key %q: %w; json fallback error: %w",
239239
namespace, authzRef.ConfigMap.Name, key, err, err2)
240240
}
241241
}

cmd/thv-proxyrunner/app/run.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func runCmdFunc(cmd *cobra.Command, args []string) error {
8080
// Create container runtime
8181
rt, err := container.NewFactory().Create(ctx)
8282
if err != nil {
83-
return fmt.Errorf("failed to create container runtime: %v", err)
83+
return fmt.Errorf("failed to create container runtime: %w", err)
8484
}
8585

8686
// Select an env var validation strategy depending on how the CLI is run:
@@ -178,7 +178,7 @@ func runWithFileBasedConfig(
178178
if envVarValidator != nil {
179179
validatedEnvVars, err := envVarValidator.Validate(ctx, imageMetadata, config, config.EnvVars)
180180
if err != nil {
181-
return fmt.Errorf("failed to validate environment variables: %v", err)
181+
return fmt.Errorf("failed to validate environment variables: %w", err)
182182
}
183183
config.EnvVars = validatedEnvVars
184184
}
@@ -187,7 +187,7 @@ func runWithFileBasedConfig(
187187
if config.EnvFileDir != "" {
188188
updatedConfig, err := config.WithEnvFilesFromDirectory(config.EnvFileDir)
189189
if err != nil {
190-
return fmt.Errorf("failed to process environment files from directory %s: %v", config.EnvFileDir, err)
190+
return fmt.Errorf("failed to process environment files from directory %s: %w", config.EnvFileDir, err)
191191
}
192192
config = updatedConfig
193193
}
@@ -199,7 +199,7 @@ func runWithFileBasedConfig(
199199

200200
workloadManager, err := workloads.NewManagerFromRuntime(rt)
201201
if err != nil {
202-
return fmt.Errorf("failed to create workload manager: %v", err)
202+
return fmt.Errorf("failed to create workload manager: %w", err)
203203
}
204204
return workloadManager.RunWorkload(ctx, config)
205205
}

cmd/thv/app/build.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ func buildCmdFunc(cmd *cobra.Command, args []string) error {
9494
dockerfileContent, err := runner.BuildFromProtocolSchemeWithName(
9595
ctx, imageManager, protocolScheme, "", buildFlags.Tag, buildArgs, true)
9696
if err != nil {
97-
return fmt.Errorf("failed to generate Dockerfile for %s: %v", protocolScheme, err)
97+
return fmt.Errorf("failed to generate Dockerfile for %s: %w", protocolScheme, err)
9898
}
9999

100100
// Write to output file if specified
101101
if buildFlags.Output != "" {
102102
if err := os.WriteFile(buildFlags.Output, []byte(dockerfileContent), 0600); err != nil {
103-
return fmt.Errorf("failed to write Dockerfile to %s: %v", buildFlags.Output, err)
103+
return fmt.Errorf("failed to write Dockerfile to %s: %w", buildFlags.Output, err)
104104
}
105105
logger.Infof("Dockerfile written to: %s", buildFlags.Output)
106106
fmt.Printf("Dockerfile written to: %s\n", buildFlags.Output)
@@ -116,7 +116,7 @@ func buildCmdFunc(cmd *cobra.Command, args []string) error {
116116
// Build the image using the new protocol handler with custom name
117117
imageName, err := runner.BuildFromProtocolSchemeWithName(ctx, imageManager, protocolScheme, "", buildFlags.Tag, buildArgs, false)
118118
if err != nil {
119-
return fmt.Errorf("failed to build container for %s: %v", protocolScheme, err)
119+
return fmt.Errorf("failed to build container for %s: %w", protocolScheme, err)
120120
}
121121

122122
logger.Infof("Successfully built container image: %s", imageName)

cmd/thv/app/inspector.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,20 @@ func inspectorCmdFunc(cmd *cobra.Command, args []string) error {
102102
tokenBytes := make([]byte, 32)
103103
_, err := rand.Read(tokenBytes)
104104
if err != nil {
105-
return fmt.Errorf("failed to generate auth token: %v", err)
105+
return fmt.Errorf("failed to generate auth token: %w", err)
106106
}
107107
authToken := hex.EncodeToString(tokenBytes)
108108

109109
// find the port of the server if it is running / exists
110110
serverPort, transportType, err := getServerPortAndTransport(ctx, serverName)
111111
if err != nil {
112-
return fmt.Errorf("failed to find server: %v", err)
112+
return fmt.Errorf("failed to find server: %w", err)
113113
}
114114

115115
imageManager := images.NewImageManager(ctx)
116116
err = imageManager.PullImage(ctx, inspector.Image)
117117
if err != nil {
118-
return fmt.Errorf("failed to pull inspector image: %v", err)
118+
return fmt.Errorf("failed to pull inspector image: %w", err)
119119
}
120120
processedImage := inspector.Image
121121

@@ -128,7 +128,7 @@ func inspectorCmdFunc(cmd *cobra.Command, args []string) error {
128128
// Create workload runtime
129129
rt, err := container.NewFactory().Create(ctx)
130130
if err != nil {
131-
return fmt.Errorf("failed to create workload runtime: %v", err)
131+
return fmt.Errorf("failed to create workload runtime: %w", err)
132132
}
133133

134134
labelsMap := map[string]string{}
@@ -150,7 +150,7 @@ func inspectorCmdFunc(cmd *cobra.Command, args []string) error {
150150
false, // Do not isolate network
151151
)
152152
if err != nil {
153-
return fmt.Errorf("failed to create inspector workload: %v", err)
153+
return fmt.Errorf("failed to create inspector workload: %w", err)
154154
}
155155

156156
// Monitor inspector readiness by checking HTTP response
@@ -185,12 +185,12 @@ func getServerPortAndTransport(ctx context.Context, serverName string) (int, typ
185185
// Instantiate the status manager and list all workloads.
186186
manager, err := workloads.NewManager(ctx)
187187
if err != nil {
188-
return 0, types.TransportTypeSSE, fmt.Errorf("failed to create status manager: %v", err)
188+
return 0, types.TransportTypeSSE, fmt.Errorf("failed to create status manager: %w", err)
189189
}
190190

191191
workloadList, err := manager.ListWorkloads(ctx, true)
192192
if err != nil {
193-
return 0, types.TransportTypeSSE, fmt.Errorf("failed to list workloads: %v", err)
193+
return 0, types.TransportTypeSSE, fmt.Errorf("failed to list workloads: %w", err)
194194
}
195195

196196
for _, c := range workloadList {

cmd/thv/app/list.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,19 @@ func listCmdFunc(cmd *cobra.Command, _ []string) error {
4444
// Instantiate the status manager.
4545
manager, err := workloads.NewManager(ctx)
4646
if err != nil {
47-
return fmt.Errorf("failed to create status manager: %v", err)
47+
return fmt.Errorf("failed to create status manager: %w", err)
4848
}
4949

5050
workloadList, err := manager.ListWorkloads(ctx, listAll, listLabelFilter...)
5151
if err != nil {
52-
return fmt.Errorf("failed to list workloads: %v", err)
52+
return fmt.Errorf("failed to list workloads: %w", err)
5353
}
5454

5555
// Apply group filtering if specified
5656
if listGroupFilter != "" {
5757
workloadList, err = workloads.FilterByGroup(workloadList, listGroupFilter)
5858
if err != nil {
59-
return fmt.Errorf("failed to filter workloads by group: %v", err)
59+
return fmt.Errorf("failed to filter workloads by group: %w", err)
6060
}
6161
}
6262

@@ -94,7 +94,7 @@ func printJSONOutput(workloadList []core.Workload) error {
9494
// Marshal to JSON
9595
jsonData, err := json.MarshalIndent(workloadList, "", " ")
9696
if err != nil {
97-
return fmt.Errorf("failed to marshal JSON: %v", err)
97+
return fmt.Errorf("failed to marshal JSON: %w", err)
9898
}
9999

100100
// Print JSON directly to stdout
@@ -121,7 +121,7 @@ func printMCPServersOutput(workloadList []core.Workload) error {
121121
"mcpServers": mcpServers,
122122
}, "", " ")
123123
if err != nil {
124-
return fmt.Errorf("failed to marshal JSON: %v", err)
124+
return fmt.Errorf("failed to marshal JSON: %w", err)
125125
}
126126

127127
// Print JSON directly to stdout

cmd/thv/app/logs.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func logsCmdFunc(cmd *cobra.Command, args []string) error {
8080

8181
manager, err := workloads.NewManager(ctx)
8282
if err != nil {
83-
return fmt.Errorf("failed to create workload manager: %v", err)
83+
return fmt.Errorf("failed to create workload manager: %w", err)
8484
}
8585

8686
if proxy {
@@ -103,7 +103,7 @@ func logsCmdFunc(cmd *cobra.Command, args []string) error {
103103
logger.Infof("Workload %s not found", workloadName)
104104
return nil
105105
}
106-
return fmt.Errorf("failed to get logs for workload %s: %v", workloadName, err)
106+
return fmt.Errorf("failed to get logs for workload %s: %w", workloadName, err)
107107
}
108108

109109
fmt.Print(logs)
@@ -142,7 +142,7 @@ func logsPruneCmdFunc(cmd *cobra.Command) error {
142142
func getLogsDirectory() (string, error) {
143143
logsDir, err := xdg.DataFile("toolhive/logs")
144144
if err != nil {
145-
return "", fmt.Errorf("failed to get logs directory path: %v", err)
145+
return "", fmt.Errorf("failed to get logs directory path: %w", err)
146146
}
147147

148148
if _, err := os.Stat(logsDir); os.IsNotExist(err) {
@@ -156,12 +156,12 @@ func getLogsDirectory() (string, error) {
156156
func getManagedContainerNames(ctx context.Context) (map[string]bool, error) {
157157
manager, err := workloads.NewManager(ctx)
158158
if err != nil {
159-
return nil, fmt.Errorf("failed to create status manager: %v", err)
159+
return nil, fmt.Errorf("failed to create status manager: %w", err)
160160
}
161161

162162
managedContainers, err := manager.ListWorkloads(ctx, true)
163163
if err != nil {
164-
return nil, fmt.Errorf("failed to list workloads: %v", err)
164+
return nil, fmt.Errorf("failed to list workloads: %w", err)
165165
}
166166

167167
managedNames := make(map[string]bool)
@@ -182,7 +182,7 @@ func getLogFiles(logsDir string) ([]string, error) {
182182

183183
logFiles, err := filepath.Glob(filepath.Join(logsDir, "*.log"))
184184
if err != nil {
185-
return nil, fmt.Errorf("failed to list log files: %v", err)
185+
return nil, fmt.Errorf("failed to list log files: %w", err)
186186
}
187187

188188
return logFiles, nil
@@ -232,7 +232,7 @@ func getProxyLogs(workloadName string) error {
232232
// Get the proxy log file path
233233
logFilePath, err := xdg.DataFile(fmt.Sprintf("toolhive/logs/%s.log", workloadName))
234234
if err != nil {
235-
return fmt.Errorf("failed to get proxy log file path: %v", err)
235+
return fmt.Errorf("failed to get proxy log file path: %w", err)
236236
}
237237

238238
// Clean the file path to prevent path traversal
@@ -255,7 +255,7 @@ func followProxyLogFile(logFilePath string) error {
255255
// Open the file
256256
file, err := os.Open(cleanLogFilePath)
257257
if err != nil {
258-
return fmt.Errorf("failed to open proxy log %s: %v", cleanLogFilePath, err)
258+
return fmt.Errorf("failed to open proxy log %s: %w", cleanLogFilePath, err)
259259
}
260260
defer file.Close()
261261

@@ -268,7 +268,7 @@ func followProxyLogFile(logFilePath string) error {
268268
// Seek to the end of the file for following
269269
_, err = file.Seek(0, 2)
270270
if err != nil {
271-
return fmt.Errorf("failed to seek to end of proxy log: %v", err)
271+
return fmt.Errorf("failed to seek to end of proxy log: %w", err)
272272
}
273273

274274
// Follow the file for new content
@@ -277,7 +277,7 @@ func followProxyLogFile(logFilePath string) error {
277277
buffer := make([]byte, 1024)
278278
n, err := file.Read(buffer)
279279
if err != nil && err.Error() != "EOF" {
280-
return fmt.Errorf("error reading proxy log: %v", err)
280+
return fmt.Errorf("error reading proxy log: %w", err)
281281
}
282282

283283
if n > 0 {

cmd/thv/app/proxy.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func proxyCmdFunc(cmd *cobra.Command, args []string) error {
235235
// Get authentication middleware for incoming requests
236236
authMiddleware, authInfoHandler, err := auth.GetAuthenticationMiddleware(ctx, oidcConfig)
237237
if err != nil {
238-
return fmt.Errorf("failed to create authentication middleware: %v", err)
238+
return fmt.Errorf("failed to create authentication middleware: %w", err)
239239
}
240240
middlewares = append(middlewares, types.NamedMiddleware{
241241
Name: "auth",
@@ -264,7 +264,7 @@ func proxyCmdFunc(cmd *cobra.Command, args []string) error {
264264
nil, // onHealthCheckFailed - not needed for local proxies
265265
middlewares...)
266266
if err := proxy.Start(ctx); err != nil {
267-
return fmt.Errorf("failed to start proxy: %v", err)
267+
return fmt.Errorf("failed to start proxy: %w", err)
268268
}
269269

270270
logger.Infof("Transparent proxy started for server %s on port %d -> %s",
@@ -397,13 +397,13 @@ func addExternalTokenMiddleware(middlewares *[]types.NamedMiddleware, tokenSourc
397397
// Create middleware using TokenSource - middleware handles token selection
398398
tokenExchangeMiddleware, err = tokenexchange.CreateMiddlewareFromTokenSource(*tokenExchangeConfig, tokenSource)
399399
if err != nil {
400-
return fmt.Errorf("failed to create token exchange middleware: %v", err)
400+
return fmt.Errorf("failed to create token exchange middleware: %w", err)
401401
}
402402
} else {
403403
// Create middleware that extracts token from Authorization header
404404
tokenExchangeMiddleware, err = tokenexchange.CreateMiddlewareFromHeader(*tokenExchangeConfig)
405405
if err != nil {
406-
return fmt.Errorf("failed to create token exchange middleware: %v", err)
406+
return fmt.Errorf("failed to create token exchange middleware: %w", err)
407407
}
408408
}
409409
*middlewares = append(*middlewares, types.NamedMiddleware{

0 commit comments

Comments
 (0)