Use case: you need to change what goes in or comes out of a conversion, or react correctly when one fails. For production-scale failure handling (retry, health, metrics), see the resilience guide - this page covers the per-call mechanics.
.BeforePDF((html, inputParam, token) => Task.FromResult(html.Replace("[{Token}]", inputParam.Value)));BeforePDF/AfterPDF live on the execution context, not the builder, so concurrent requests never share customization state - see Extension points in the architecture guide. Sample: OnlyAtServer/CustomHooks.
services.AddHtmlPdfService<DataSavePDF, string>((cfg) => cfg. ...);
// ...
.AfterPDF((pdfBytes, inputParam, token) => { /* save it, return the path */ });Samples: ClientCustomSendHttp / WebHtmlToPdf.CustomSaveFileServer.
if (!pdfresult.IsSuccess)
{
switch (pdfresult.Error!.Code)
{
case ErrorCode.PoolExhausted: /* see the retry how-to below */ break;
case ErrorCode.InvalidRequest: /* fix the request, don't retry */ break;
default:
if (pdfresult.Error.Retryable) { /* retryable - e.g. Timeout, Canceled, RenderFailed */ }
else { /* log pdfresult.Error.Message */ }
break;
}
}See ADR-001 for why failures are a structured ErrorInfo, not a raw exception.
ErrorCode.PoolExhausted comes with a suggested ErrorInfo.RetryAfterSeconds - the library never retries on your behalf, so your own loop decides. Full flow and diagram: resilience guide - backpressure. Sample: RetryAfterBackpressure.