mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-07-02 00:17:40 +08:00
refactor: make client- and operator-facing error messages clearer and actionable
This commit is contained in:
@@ -85,6 +85,15 @@ If a change violates backward compatibility, flag it as a breaking change in the
|
|||||||
- No panics in production code paths.
|
- No panics in production code paths.
|
||||||
- Validate input defensively.
|
- Validate input defensively.
|
||||||
|
|
||||||
|
### Error messages
|
||||||
|
|
||||||
|
Client- and operator-facing error messages state what failed, why when non-obvious, and how to fix it when a fix exists. Internal errors (the wrapped `fmt.Errorf` chains that only reach logs) are exempt; keep them precise and technical.
|
||||||
|
|
||||||
|
- Client (HTTP response body): name the offending form field and its valid values. Never return a bare `http.StatusText()`.
|
||||||
|
- Operator (startup, `Provision`, `Validate`): name the environment variable or flag to set, plus the path or value checked.
|
||||||
|
- Security and filtering errors stay generic for clients. Don't reveal allow/deny lists or private-IP policy. Log the specific reason for operators.
|
||||||
|
- No hedging ("while others may have failed"). No raw `os.Stat` or exec output in the human-facing remedy.
|
||||||
|
|
||||||
### Logging
|
### Logging
|
||||||
|
|
||||||
Use `gotenberg.Logger(mod)` to get the module's slog logger during `Provision()`. All log calls must be context-aware: `logger.DebugContext(ctx, msg)`, `logger.InfoContext(ctx, msg)`, `logger.ErrorContext(ctx, msg)`. This propagates trace/span IDs into structured logs when OpenTelemetry is active.
|
Use `gotenberg.Logger(mod)` to get the module's slog logger during `Provision()`. All log calls must be context-aware: `logger.DebugContext(ctx, msg)`, `logger.InfoContext(ctx, msg)`, `logger.ErrorContext(ctx, msg)`. This propagates trace/span IDs into structured logs when OpenTelemetry is active.
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ func newContext(echoCtx echo.Context, logger *slog.Logger, fs *gotenberg.FileSys
|
|||||||
if bodyLimit != 0 && newTotal > bodyLimit {
|
if bodyLimit != 0 && newTotal > bodyLimit {
|
||||||
return WrapError(
|
return WrapError(
|
||||||
fmt.Errorf("body limit reached (> %d)", bodyLimit),
|
fmt.Errorf("body limit reached (> %d)", bodyLimit),
|
||||||
NewSentinelHttpError(http.StatusRequestEntityTooLarge, http.StatusText(http.StatusRequestEntityTooLarge)),
|
NewSentinelHttpError(http.StatusRequestEntityTooLarge, "The request body exceeds the configured size limit. Increase it with --api-body-limit, or send a smaller request."),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func ParseError(err error) (int, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, context.DeadlineExceeded) {
|
if errors.Is(err, context.DeadlineExceeded) {
|
||||||
return http.StatusServiceUnavailable, http.StatusText(http.StatusServiceUnavailable)
|
return http.StatusServiceUnavailable, "The request exceeded the time limit. Increase it with --api-timeout, or reduce the workload."
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrFiltered) {
|
if errors.Is(err, gotenberg.ErrFiltered) {
|
||||||
@@ -51,27 +51,27 @@ func ParseError(err error) (int, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrMaximumQueueSizeExceeded) {
|
if errors.Is(err, gotenberg.ErrMaximumQueueSizeExceeded) {
|
||||||
return http.StatusTooManyRequests, http.StatusText(http.StatusTooManyRequests)
|
return http.StatusTooManyRequests, "The request queue is full. Retry shortly, or raise the limit with --chromium-max-queue-size or --libreoffice-max-queue-size."
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrPdfSplitModeNotSupported) {
|
if errors.Is(err, gotenberg.ErrPdfSplitModeNotSupported) {
|
||||||
return http.StatusBadRequest, "At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues"
|
return http.StatusBadRequest, "The requested split mode is not supported, or no PDF engine could process it. Valid modes: 'intervals', 'pages'."
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrPdfFormatNotSupported) {
|
if errors.Is(err, gotenberg.ErrPdfFormatNotSupported) {
|
||||||
return http.StatusBadRequest, "At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues"
|
return http.StatusBadRequest, "The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA."
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrPdfEngineMetadataValueNotSupported) {
|
if errors.Is(err, gotenberg.ErrPdfEngineMetadataValueNotSupported) {
|
||||||
return http.StatusBadRequest, "At least one PDF engine cannot process the requested metadata, while others may have failed to convert due to different issues"
|
return http.StatusBadRequest, "The requested metadata could not be written; ensure values are valid and free of control characters."
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrPdfStampSourceNotSupported) {
|
if errors.Is(err, gotenberg.ErrPdfStampSourceNotSupported) {
|
||||||
return http.StatusBadRequest, "At least one PDF engine cannot process the requested stamp source type, while others may have failed due to different issues"
|
return http.StatusBadRequest, "The requested stamp source is not supported, or no PDF engine could process it. Valid sources: 'text', 'image', 'pdf'."
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, gotenberg.ErrPdfRotateAngleNotSupported) {
|
if errors.Is(err, gotenberg.ErrPdfRotateAngleNotSupported) {
|
||||||
return http.StatusBadRequest, "At least one PDF engine cannot process the requested rotation angle, while others may have failed due to different issues"
|
return http.StatusBadRequest, "The requested rotation angle is not supported. Valid angles: 90, 180, 270."
|
||||||
}
|
}
|
||||||
|
|
||||||
if invalidArgsError, ok := errors.AsType[*gotenberg.PdfEngineInvalidArgsError](err); ok {
|
if invalidArgsError, ok := errors.AsType[*gotenberg.PdfEngineInvalidArgsError](err); ok {
|
||||||
|
|||||||
@@ -486,12 +486,12 @@ func (mod *Chromium) Provision(ctx *gotenberg.Context) error {
|
|||||||
|
|
||||||
binPath, ok := os.LookupEnv("CHROMIUM_BIN_PATH")
|
binPath, ok := os.LookupEnv("CHROMIUM_BIN_PATH")
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("CHROMIUM_BIN_PATH environment variable is not set")
|
return errors.New("CHROMIUM_BIN_PATH environment variable is not set; set it to the absolute path of the Chromium or Chrome binary")
|
||||||
}
|
}
|
||||||
|
|
||||||
hyphenDataDirPath, ok := os.LookupEnv("CHROMIUM_HYPHEN_DATA_DIR_PATH")
|
hyphenDataDirPath, ok := os.LookupEnv("CHROMIUM_HYPHEN_DATA_DIR_PATH")
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("CHROMIUM_HYPHEN_DATA_DIR_PATH environment variable is not set")
|
return errors.New("CHROMIUM_HYPHEN_DATA_DIR_PATH environment variable is not set; set it to the absolute path of the Chromium hyphenation data directory (it ships in the Gotenberg image)")
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.args = browserArguments{
|
mod.args = browserArguments{
|
||||||
@@ -664,12 +664,12 @@ func (mod *Chromium) Validate() error {
|
|||||||
|
|
||||||
_, err := os.Stat(mod.args.binPath)
|
_, err := os.Stat(mod.args.binPath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return fmt.Errorf("chromium binary path does not exist: %w", err)
|
return fmt.Errorf("Chromium binary does not exist at %q; check the CHROMIUM_BIN_PATH environment variable: %w", mod.args.binPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = os.Stat(mod.args.hyphenDataDirPath)
|
_, err = os.Stat(mod.args.hyphenDataDirPath)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return fmt.Errorf("chromium hyphen-data directory path does not exist: %w", err)
|
return fmt.Errorf("Chromium hyphenation data directory does not exist at %q; check the CHROMIUM_HYPHEN_DATA_DIR_PATH environment variable (it ships in the Gotenberg image): %w", mod.args.hyphenDataDirPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -487,12 +487,12 @@ func (a *Api) Validate() error {
|
|||||||
|
|
||||||
_, statErr := os.Stat(a.args.binPath)
|
_, statErr := os.Stat(a.args.binPath)
|
||||||
if os.IsNotExist(statErr) {
|
if os.IsNotExist(statErr) {
|
||||||
err = errors.Join(err, fmt.Errorf("LibreOffice binary path does not exist: %w", statErr))
|
err = errors.Join(err, fmt.Errorf("LibreOffice binary does not exist at %q; check the LIBREOFFICE_BIN_PATH environment variable: %w", a.args.binPath, statErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
_, statErr = os.Stat(a.args.unoBinPath)
|
_, statErr = os.Stat(a.args.unoBinPath)
|
||||||
if os.IsNotExist(statErr) {
|
if os.IsNotExist(statErr) {
|
||||||
err = errors.Join(err, fmt.Errorf("unoconverter binary path does not exist: %w", statErr))
|
err = errors.Join(err, fmt.Errorf("unoconverter binary does not exist at %q; check the UNOCONVERTER_BIN_PATH environment variable: %w", a.args.unoBinPath, statErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ func (p *libreOfficeProcess) Start(logger *slog.Logger) error {
|
|||||||
select {
|
select {
|
||||||
case err = <-connChan:
|
case err = <-connChan:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("LibreOffice socket not available: %w", err)
|
return fmt.Errorf("LibreOffice did not become available within the start timeout; increase --libreoffice-start-timeout or check system resources: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.DebugContext(context.Background(), "LibreOffice socket available")
|
logger.DebugContext(context.Background(), "LibreOffice socket available")
|
||||||
@@ -204,7 +204,7 @@ func (p *libreOfficeProcess) Start(logger *slog.Logger) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
case err = <-waitChan:
|
case err = <-waitChan:
|
||||||
return fmt.Errorf("LibreOffice process exited: %w", err)
|
return fmt.Errorf("LibreOffice exited unexpectedly during startup; check system resources such as memory, disk, and permissions: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap
|
|||||||
fmt.Errorf("convert to PDF: %w", err),
|
fmt.Errorf("convert to PDF: %w", err),
|
||||||
api.NewSentinelHttpError(
|
api.NewSentinelHttpError(
|
||||||
http.StatusBadRequest,
|
http.StatusBadRequest,
|
||||||
fmt.Sprintf("A PDF format in '%+v' is not supported", pdfFormats),
|
fmt.Sprintf("The PDF format '%s' is not supported. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.", pdfFormats.PdfA),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
|
|||||||
// actually exist.
|
// actually exist.
|
||||||
func (mod *PdfEngines) Validate() error {
|
func (mod *PdfEngines) Validate() error {
|
||||||
if len(mod.engines) == 0 {
|
if len(mod.engines) == 0 {
|
||||||
return errors.New("no PDF engine")
|
return errors.New("no PDF engine is available; enable at least one engine module (e.g. qpdf, pdfcpu, pdftk, libreoffice-pdfengine, exiftool)")
|
||||||
}
|
}
|
||||||
|
|
||||||
availableEngines := make([]string, len(mod.engines))
|
availableEngines := make([]string, len(mod.engines))
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func (engine *QPdf) Descriptor() gotenberg.ModuleDescriptor {
|
|||||||
func (engine *QPdf) Provision(ctx *gotenberg.Context) error {
|
func (engine *QPdf) Provision(ctx *gotenberg.Context) error {
|
||||||
binPath, ok := os.LookupEnv("QPDF_BIN_PATH")
|
binPath, ok := os.LookupEnv("QPDF_BIN_PATH")
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("QPDF_BIN_PATH environment variable is not set")
|
return errors.New("QPDF_BIN_PATH environment variable is not set; set it to the absolute path of the qpdf binary")
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.binPath = binPath
|
engine.binPath = binPath
|
||||||
|
|||||||
@@ -735,7 +735,7 @@ Feature: /forms/chromium/convert/html
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
The requested split mode is not supported, or no PDF engine could process it. Valid modes: 'intervals', 'pages'.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page-1-html/index.html | file |
|
| files | testdata/page-1-html/index.html | file |
|
||||||
@@ -744,7 +744,7 @@ Feature: /forms/chromium/convert/html
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page-1-html/index.html | file |
|
| files | testdata/page-1-html/index.html | file |
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ Feature: /forms/chromium/convert/markdown
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
The requested split mode is not supported, or no PDF engine could process it. Valid modes: 'intervals', 'pages'.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page-1-markdown/index.html | file |
|
| files | testdata/page-1-markdown/index.html | file |
|
||||||
@@ -662,7 +662,7 @@ Feature: /forms/chromium/convert/markdown
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page-1-markdown/index.html | file |
|
| files | testdata/page-1-markdown/index.html | file |
|
||||||
|
|||||||
@@ -815,7 +815,7 @@ Feature: /forms/chromium/convert/url
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
The requested split mode is not supported, or no PDF engine could process it. Valid modes: 'intervals', 'pages'.
|
||||||
"""
|
"""
|
||||||
Given I have a static server
|
Given I have a static server
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||||
@@ -825,7 +825,7 @@ Feature: /forms/chromium/convert/url
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
Given I have a static server
|
Given I have a static server
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ Feature: /forms/libreoffice/convert
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
The requested split mode is not supported, or no PDF engine could process it. Valid modes: 'intervals', 'pages'.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||||
| files | testdata/pages_3.docx | file |
|
| files | testdata/pages_3.docx | file |
|
||||||
@@ -322,7 +322,7 @@ Feature: /forms/libreoffice/convert
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
A PDF format in '{PdfA:foo PdfUa:false}' is not supported
|
The PDF format 'foo' is not supported. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page_1.docx | file |
|
| files | testdata/page_1.docx | file |
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ Feature: /forms/pdfengines/convert
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page_1.pdf | file |
|
| files | testdata/page_1.pdf | file |
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ Feature: /forms/pdfengines/merge
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||||
| files | testdata/page_1.pdf | file |
|
| files | testdata/page_1.pdf | file |
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ Feature: /forms/pdfengines/metadata/{write|read}
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should contain string:
|
Then the response body should contain string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested metadata
|
The requested metadata could not be written
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Scenario: POST /forms/pdfengines/metadata/write (Reject Group-Prefixed Dangerous Tag)
|
Scenario: POST /forms/pdfengines/metadata/write (Reject Group-Prefixed Dangerous Tag)
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ Feature: /forms/pdfengines/split
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
The requested split mode is not supported, or no PDF engine could process it. Valid modes: 'intervals', 'pages'.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||||
| files | testdata/pages_3.pdf | file |
|
| files | testdata/pages_3.pdf | file |
|
||||||
@@ -294,7 +294,7 @@ Feature: /forms/pdfengines/split
|
|||||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
The requested PDF format is not supported, or no PDF engine could apply it. Valid formats include PDF/A-1b, PDF/A-2b, PDF/A-3b, and PDF/UA.
|
||||||
"""
|
"""
|
||||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||||
| files | testdata/pages_3.pdf | file |
|
| files | testdata/pages_3.pdf | file |
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ Feature: /forms/pdfengines/stamp
|
|||||||
Then the response status code should be 400
|
Then the response status code should be 400
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested stamp source type, while others may have failed due to different issues
|
The requested stamp source is not supported, or no PDF engine could process it. Valid sources: 'text', 'image', 'pdf'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@download-from
|
@download-from
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ Feature: /forms/pdfengines/watermark
|
|||||||
Then the response status code should be 400
|
Then the response status code should be 400
|
||||||
Then the response body should match string:
|
Then the response body should match string:
|
||||||
"""
|
"""
|
||||||
At least one PDF engine cannot process the requested stamp source type, while others may have failed due to different issues
|
The requested stamp source is not supported, or no PDF engine could process it. Valid sources: 'text', 'image', 'pdf'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@download-from
|
@download-from
|
||||||
|
|||||||
Reference in New Issue
Block a user