diff --git a/CLAUDE.md b/CLAUDE.md index 2fb9343..5f35b3c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -80,6 +80,8 @@ type ProfileManager interface { - Licence: EUPL-1.2 — new files need `// SPDX-License-Identifier: EUPL-1.2` - Security-first: do not weaken HMAC, challenge-response, Zip Slip defence, or rate limiting - Use `logging` package only — no `fmt.Println` or `log.Printf` in library code +- Error handling: use `coreerr.E()` from `go-log` — never `fmt.Errorf` or `errors.New` in library code +- File I/O: use `coreio.Local` from `go-io` — never `os.ReadFile`/`os.WriteFile` in library code (exception: `os.OpenFile` for streaming writes where `coreio` lacks support) - Hot-path debug logging uses sampling pattern: `if counter.Add(1)%interval == 0` ### Transport test helper diff --git a/node/bundle.go b/node/bundle.go index 386bb8f..16af455 100644 --- a/node/bundle.go +++ b/node/bundle.go @@ -311,7 +311,7 @@ func extractTarball(tarData []byte, destDir string) (string, error) { f, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(hdr.Mode)) if err != nil { - return "", err + return "", coreerr.E("extractTarball", "failed to create file "+hdr.Name, err) } // Limit file size to prevent decompression bombs (100MB max per file) @@ -320,7 +320,7 @@ func extractTarball(tarData []byte, destDir string) (string, error) { written, err := io.Copy(f, limitedReader) f.Close() if err != nil { - return "", err + return "", coreerr.E("extractTarball", "failed to write file "+hdr.Name, err) } if written > maxFileSize { coreio.Local.Delete(fullPath)