OP-MERGE-DOCUMENTS: Merge documents¶
Merges a set of input documents into one output document, converting any non-PDF inputs to PDF first, and optionally producing PDF/A output.
| Field | Value |
|---|---|
| Operation ID | OP-MERGE-DOCUMENTS |
| Trigger | Client submits POST v1/merge with a MergeRequest body |
| Entry endpoint | POST v1/merge |
| Owning component | MergeController.Merge(MergeRequest) → IPdfService.Merge(request) |
| Inputs | MergeRequest body (Documents array, Options) |
| Outputs | PdfResult (Status, Message, Document, TrackingId); a PDFTracking row created/updated |
| Failure response | A null body fails as a framework error; other caught exceptions are logged and returned as Ok(new PdfResult(message)) — HTTP 200 |
Steps¶
Enforce.ArgumentNotNull(request, "request")runs before thetryblock (BR-PDFAPI-001).- On failure (
request == null): the exception escapes to the framework — not caught by the action, so noPdfResultenvelope is produced; the framework produces exception detail (IncludeErrorDetailPolicy.Always) beforeApiResponseHandlerruns, and the final client-visible envelope is unknown** (see Endpoints: Error response shape). request.Options ??= new PdfOptions()substitutes a default (non-PDF/A) options object when the caller omittedOptions(BR-PDFAPI-002).- The remaining call is wrapped in
try/catch(BR-PDFAPI-017). - On any exception:
_logService.LogException("pdfapi", "Merge", "<detail>", ex), thenOk(new PdfResult(ex.Message, request: request))— HTTP200. - If tracking is enabled (default, or forced on by
SendHeatEmailOnFailure, BR-PDFAPI-010),PdfTrackingService.CreateTrackingRecordinserts aPDFTrackingrow. - Each non-PDF input document is converted to PDF first; if any pre-conversion fails, a
PdfExceptionis thrown and the entire merge is abandoned — no partial output is produced (BR-PDFAPI-006). PdfMerger.Merge(Syncfusion.Pdf.PdfDocument.Merge) combines the converted/validated documents into one output.
This merge logic is implemented in PdfApi.SyncFusionCore (PdfMerger.Merge), documented in full at Merge document ranges into one PDF (OP-SFC-012); its behavior is summarized here only as observed on this request path.
Origin: The document-merge behavior described in this step is implemented in
PdfApi.SyncFusionCore, not inPdfAPI. See the linked operation page for the full delegated logic. 7. IfOptions.IsPdfaand the merged output failsValidatePdfA,OutputFormatis silently downgraded toPdfFormat.Pdfrather than failing the request (BR-PDFAPI-007). 8. On the ActivePDF processor: a PDF/A production failure is retried as plain PDF, and configuredpdfApi.ErrorsToRetryerror codes trigger a whole-operation retry (BR-PDFAPI-020). 9.FinalizeResultstampsTrackingId,PdfProcessorType,FilePath, then persists the terminal tracking status viaPdfTrackingService.UpdateTrackingRecord. 10. If the result failed andSendHeatEmailOnFailureis set, an incident email is sent (BR-PDFAPI-015). 11. The controller returnsOk(result)— HTTP200regardless of whether the merge succeeded or failed.
Process flow¶
The following diagram shows the pre-conversion, merge, PDF/A-downgrade, and incident-email sequence for a merge request.
flowchart TD
A["POST v1/merge"] --> B{"request null?"}
B -->|Yes| C["Framework 500 error, no PdfResult"]
B -->|No| D["Substitute default Options if null"]
D --> E["Create tracking record"]
E --> F["Convert non-PDF inputs to PDF"]
F -->|Any pre-conversion fails| G["PdfException: merge abandoned"]
F -->|All succeed| H["PdfMerger.Merge combines documents"]
H --> I{"IsPdfa requested and<br>validation fails?"}
I -->|Yes| J["Silently downgrade to Pdf"]
I -->|No| K["Keep requested format"]
J --> L["FinalizeResult: persist terminal status"]
K --> L
L --> M{"Result failed and<br>SendHeatEmailOnFailure?"}
M -->|Yes| N["Send incident email"]
M -->|No| O["Ok result"]
N --> O
Transaction and side effects¶
| Aspect | Finding |
|---|---|
| Unit of work | IUnitOfWorkFactory("oracle"), InstancePerRequest |
| Commit point | PdfTrackingService.CreateTrackingRecord and UpdateTrackingRecord, each bracketed by _uow.Begin()/_uow.Commit() |
| Records written | PDFTracking (data model) |
| Downstream calls | Outbound SMTP email on failure when SendHeatEmailOnFailure is set |
| Repeat-call behavior | Each call creates a new tracking record; not idempotent |
Logging¶
| Surface | Written content |
|---|---|
ILogService.LogException |
"pdfapi", "Merge", and exception detail, on any caught failure |
Error handling¶
- Null request body: escapes to the framework before the
tryblock, producing framework exception detail beforeApiResponseHandlerruns; the final client-visible envelope is unknown**, and noPdfResultis produced (BR-PDFAPI-001). - Pre-conversion failure on any input:
PdfException, caught, logged, entire merge abandoned,200with a failurePdfResult(BR-PDFAPI-006). - PDF/A requested but not achieved: not an error — silent downgrade (BR-PDFAPI-007).
Related documentation¶
- API index
- Overview
- Architecture
- Endpoints
- Authentication and authorization
- Dependencies
- Configuration
- Operations and processes
- Business rules
- Data model
- Operational runbook
- Tech debt
Note: Statements marked with
**could not be confirmed; treat as unknown until verified.
Sources¶
- PdfAPI\Controllers\v1\MergeController.cs
- PdfAPI\Services\PdfService.cs
- PdfAPI\Services\PdfTrackingService.cs
- PdfAPI\Services\Syncfusion\SyncfusionPdfService.cs
- PdfAPI\Services\ActivePdf\ActivePdfService.cs
- PdfAPI.Core\Request\MergeRequest.cs