From 05bde9633429c6ea2a3956fcd6e700edbddcd444 Mon Sep 17 00:00:00 2001 From: Julien Neuhart Date: Wed, 12 Aug 2026 21:50:14 +0200 Subject: [PATCH] refactor(qpdf): make embed-metadata logging context-aware --- pkg/modules/qpdf/qpdf.go | 18 +++++++++--------- pkg/modules/qpdf/qpdf_test.go | 17 +++++++++-------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/pkg/modules/qpdf/qpdf.go b/pkg/modules/qpdf/qpdf.go index 2229664c..67f5501d 100644 --- a/pkg/modules/qpdf/qpdf.go +++ b/pkg/modules/qpdf/qpdf.go @@ -454,7 +454,7 @@ func (engine *QPdf) EmbedFilesMetadata(ctx context.Context, logger *slog.Logger, return err } - catalogRef, catalogValue, filespecRefs, updateObjects := patchFilespecMetadata(logger, objects, metadata) + catalogRef, catalogValue, filespecRefs, updateObjects := patchFilespecMetadata(ctx, logger, objects, metadata) if len(filespecRefs) == 0 { span.SetStatus(codes.Ok, "") return nil @@ -506,7 +506,7 @@ func parsePdfObjects(output []byte) (map[string]json.RawMessage, error) { // metadata keys. It sets /AFRelationship and /Subtype on matching objects // and returns the catalog reference, catalog value, filespec references, // and the update objects map. -func patchFilespecMetadata(logger *slog.Logger, objects map[string]json.RawMessage, metadata map[string]map[string]string) (string, map[string]any, []string, map[string]any) { +func patchFilespecMetadata(ctx context.Context, logger *slog.Logger, objects map[string]json.RawMessage, metadata map[string]map[string]string) (string, map[string]any, []string, map[string]any) { updateObjects := make(map[string]any) var catalogRef string var catalogValue map[string]any @@ -556,7 +556,7 @@ func patchFilespecMetadata(logger *slog.Logger, objects map[string]json.RawMessa if ef, ok := value["/EF"].(map[string]any); ok { efRef, _ := ef["/F"].(string) if efRef != "" { - setStreamSubtype(logger, objects, updateObjects, efRef, mimeType) + setStreamSubtype(ctx, logger, objects, updateObjects, efRef, mimeType) } } } @@ -653,38 +653,38 @@ func (engine *QPdf) writeAndApplyUpdate(ctx context.Context, logger *slog.Logger // setStreamSubtype finds a stream object by reference and sets the /Subtype // key in its dict. -func setStreamSubtype(logger *slog.Logger, objects map[string]json.RawMessage, updateObjects map[string]any, ref, mimeType string) { +func setStreamSubtype(ctx context.Context, logger *slog.Logger, objects map[string]json.RawMessage, updateObjects map[string]any, ref, mimeType string) { objKey := ref if !strings.HasPrefix(objKey, "obj:") { objKey = "obj:" + objKey } raw, ok := objects[objKey] if !ok { - logger.Warn(fmt.Sprintf("set stream subtype on %s: object not found", ref)) + logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: object not found", ref)) return } var obj map[string]json.RawMessage if err := json.Unmarshal(raw, &obj); err != nil { - logger.Warn(fmt.Sprintf("set stream subtype on %s: unmarshal object: %s", ref, err)) + logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: unmarshal object: %s", ref, err)) return } streamRaw, ok := obj["stream"] if !ok { - logger.Warn(fmt.Sprintf("set stream subtype on %s: no stream key", ref)) + logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: no stream key", ref)) return } var stream map[string]any if err := json.Unmarshal(streamRaw, &stream); err != nil { - logger.Warn(fmt.Sprintf("set stream subtype on %s: unmarshal stream: %s", ref, err)) + logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: unmarshal stream: %s", ref, err)) return } dict, ok := stream["dict"].(map[string]any) if !ok { - logger.Warn(fmt.Sprintf("set stream subtype on %s: stream dict is not a map", ref)) + logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: stream dict is not a map", ref)) return } diff --git a/pkg/modules/qpdf/qpdf_test.go b/pkg/modules/qpdf/qpdf_test.go index 1c615696..c5f7cbe3 100644 --- a/pkg/modules/qpdf/qpdf_test.go +++ b/pkg/modules/qpdf/qpdf_test.go @@ -1,6 +1,7 @@ package qpdf import ( + "context" "encoding/json" "log/slog" "os" @@ -99,7 +100,7 @@ func TestPatchFilespecMetadata(t *testing.T) { "factur-x.xml": {"relationship": "Data"}, } - catalogRef, _, filespecRefs, updateObjects := patchFilespecMetadata(logger, objects, metadata) + catalogRef, _, filespecRefs, updateObjects := patchFilespecMetadata(context.Background(), logger, objects, metadata) if catalogRef != "obj:1 0 R" { t.Errorf("catalogRef = %q, want %q", catalogRef, "obj:1 0 R") @@ -125,7 +126,7 @@ func TestPatchFilespecMetadata(t *testing.T) { "factur-x.xml": {"relationship": "Data"}, } - _, _, filespecRefs, _ := patchFilespecMetadata(logger, objects, metadata) + _, _, filespecRefs, _ := patchFilespecMetadata(context.Background(), logger, objects, metadata) if len(filespecRefs) != 0 { t.Errorf("filespecRefs = %v, want empty", filespecRefs) } @@ -139,7 +140,7 @@ func TestPatchFilespecMetadata(t *testing.T) { "factur-x.xml": {"relationship": "Alternative"}, } - _, _, filespecRefs, updateObjects := patchFilespecMetadata(logger, objects, metadata) + _, _, filespecRefs, updateObjects := patchFilespecMetadata(context.Background(), logger, objects, metadata) if len(filespecRefs) != 1 { t.Fatalf("filespecRefs = %v, want 1 entry", filespecRefs) } @@ -158,7 +159,7 @@ func TestPatchFilespecMetadata(t *testing.T) { "factur-x.xml": {"mimeType": "text/xml"}, } - _, _, _, updateObjects := patchFilespecMetadata(logger, objects, metadata) + _, _, _, updateObjects := patchFilespecMetadata(context.Background(), logger, objects, metadata) streamObj, ok := updateObjects["obj:3 0 R"] if !ok { t.Fatal("expected obj:3 0 R in updateObjects") @@ -223,7 +224,7 @@ func TestSetStreamSubtype(t *testing.T) { } updateObjects := make(map[string]any) - setStreamSubtype(logger, objects, updateObjects, "obj:3 0 R", "text/xml") + setStreamSubtype(context.Background(), logger, objects, updateObjects, "obj:3 0 R", "text/xml") streamObj := updateObjects["obj:3 0 R"].(map[string]any)["stream"].(map[string]any) dict := streamObj["dict"].(map[string]any) @@ -238,7 +239,7 @@ func TestSetStreamSubtype(t *testing.T) { } updateObjects := make(map[string]any) - setStreamSubtype(logger, objects, updateObjects, "5 0 R", "application/pdf") + setStreamSubtype(context.Background(), logger, objects, updateObjects, "5 0 R", "application/pdf") if _, ok := updateObjects["obj:5 0 R"]; !ok { t.Error("expected obj:5 0 R in updateObjects") @@ -249,7 +250,7 @@ func TestSetStreamSubtype(t *testing.T) { objects := map[string]json.RawMessage{} updateObjects := make(map[string]any) - setStreamSubtype(logger, objects, updateObjects, "obj:99 0 R", "text/xml") + setStreamSubtype(context.Background(), logger, objects, updateObjects, "obj:99 0 R", "text/xml") if len(updateObjects) != 0 { t.Error("expected no updates for missing object") @@ -262,7 +263,7 @@ func TestSetStreamSubtype(t *testing.T) { } updateObjects := make(map[string]any) - setStreamSubtype(logger, objects, updateObjects, "obj:3 0 R", "text/xml") + setStreamSubtype(context.Background(), logger, objects, updateObjects, "obj:3 0 R", "text/xml") if len(updateObjects) != 0 { t.Error("expected no updates for non-stream object")