From d6ebc7f230a03a4ed449771efb86919decb01599 Mon Sep 17 00:00:00 2001 From: Julien Neuhart Date: Wed, 3 Sep 2025 20:41:30 +0200 Subject: [PATCH] chore(pdfengines): better custom error message if invalid args --- go.sum | 4 ---- pkg/gotenberg/pdfengine.go | 24 +++++++++++++++---- pkg/modules/api/middlewares.go | 5 ++++ pkg/modules/pdfengines/routes.go | 10 -------- pkg/modules/pdftk/pdftk.go | 2 +- .../features/pdfengines_encrypt.feature | 2 +- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/go.sum b/go.sum index f8f61cc5..6e24f126 100644 --- a/go.sum +++ b/go.sum @@ -271,8 +271,6 @@ github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= -github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/common v0.66.0 h1:K/rJPHrG3+AoQs50r2+0t7zMnMzek2Vbv31OFVsMeVY= github.com/prometheus/common v0.66.0/go.mod h1:Ux6NtV1B4LatamKE63tJBntoxD++xmtI/lK0VtEplN4= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= @@ -293,8 +291,6 @@ github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= -github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/pkg/gotenberg/pdfengine.go b/pkg/gotenberg/pdfengine.go index 78e6e53f..e1e37eda 100644 --- a/pkg/gotenberg/pdfengine.go +++ b/pkg/gotenberg/pdfengine.go @@ -3,6 +3,7 @@ package gotenberg import ( "context" "errors" + "fmt" "go.uber.org/zap" ) @@ -27,12 +28,27 @@ var ( // ErrPdfEncryptionNotSupported is returned when encryption // is not supported by the PDF engine. ErrPdfEncryptionNotSupported = errors.New("encryption not supported") - - // ErrPdfEngineEncryptionPasswordsNotSupported is returned when provided - // passwords are not supported by the PDF engine. - ErrPdfEngineEncryptionPasswordsNotSupported = errors.New("passwords not supported") ) +// PdfEngineInvalidArgsError represents an error returned by a PDF engine when +// invalid arguments are provided. It includes the name of the engine and a +// detailed message describing the issue. +type PdfEngineInvalidArgsError struct { + engine string + msg string +} + +// Error implements the error interface. +func (e *PdfEngineInvalidArgsError) Error() string { + return fmt.Sprintf("%s: %s", e.engine, e.msg) +} + +// NewPdfEngineInvalidArgs creates a new PdfEngineInvalidArgsError with the +// given engine name and message. +func NewPdfEngineInvalidArgs(engine, msg string) error { + return &PdfEngineInvalidArgsError{engine, msg} +} + const ( // SplitModeIntervals represents a mode where a PDF is split at specific // intervals. diff --git a/pkg/modules/api/middlewares.go b/pkg/modules/api/middlewares.go index 176d6f4d..a9149efe 100644 --- a/pkg/modules/api/middlewares.go +++ b/pkg/modules/api/middlewares.go @@ -61,6 +61,11 @@ func ParseError(err error) (int, string) { return http.StatusBadRequest, "At least one PDF engine cannot process the requested metadata, while others may have failed to convert due to different issues" } + var invalidArgsError *gotenberg.PdfEngineInvalidArgsError + if errors.As(err, &invalidArgsError) { + return http.StatusBadRequest, invalidArgsError.Error() + } + var httpErr HttpError if errors.As(err, &httpErr) { return httpErr.HttpError() diff --git a/pkg/modules/pdfengines/routes.go b/pkg/modules/pdfengines/routes.go index 63f8003c..ce9135cb 100644 --- a/pkg/modules/pdfengines/routes.go +++ b/pkg/modules/pdfengines/routes.go @@ -270,16 +270,6 @@ func EncryptPdfStub(ctx *api.Context, engine gotenberg.PdfEngine, userPassword, for _, inputPath := range inputPaths { err := engine.Encrypt(ctx, ctx.Log(), inputPath, userPassword, ownerPassword) if err != nil { - if errors.Is(err, gotenberg.ErrPdfEngineEncryptionPasswordsNotSupported) { - return api.WrapError( - err, - api.NewSentinelHttpError( - http.StatusBadRequest, - "Invalid form data: both 'userPassword' and 'ownerPassword' form fields must be provided and different", - ), - ) - } - return fmt.Errorf("encrypt PDF '%s': %w", inputPath, err) } } diff --git a/pkg/modules/pdftk/pdftk.go b/pkg/modules/pdftk/pdftk.go index 5a853e39..655cbd49 100644 --- a/pkg/modules/pdftk/pdftk.go +++ b/pkg/modules/pdftk/pdftk.go @@ -152,7 +152,7 @@ func (engine *PdfTk) Encrypt(ctx context.Context, logger *zap.Logger, inputPath, } if ownerPassword == userPassword || ownerPassword == "" { - return gotenberg.ErrPdfEngineEncryptionPasswordsNotSupported + return gotenberg.NewPdfEngineInvalidArgs("pdftk", "both 'userPassword' and 'ownerPassword' must be provided and different. Consider switching to another PDF engine if this behavior does not work with your workflow") } // Create a temp output file in the same directory. diff --git a/test/integration/features/pdfengines_encrypt.feature b/test/integration/features/pdfengines_encrypt.feature index 471e28a3..6ed48f12 100644 --- a/test/integration/features/pdfengines_encrypt.feature +++ b/test/integration/features/pdfengines_encrypt.feature @@ -54,7 +54,7 @@ Feature: /forms/pdfengines/encrypt Then the response status code should be 400 Then the response body should match string: """ - Invalid form data: both 'userPassword' and 'ownerPassword' form fields must be provided and different + pdftk: both 'userPassword' and 'ownerPassword' must be provided and different. Consider switching to another PDF engine if this behavior does not work with your workflow """ Scenario: POST /forms/pdfengines/encrypt (PDFtk - both user and owner passwords)