generate_pdf_from_url

Function generate_pdf_from_url 

Source
pub fn generate_pdf_from_url(
    pool: &Mutex<BrowserPool>,
    request: &PdfFromUrlRequest,
) -> Result<PdfResponse, PdfServiceError>
Expand description

Generate a PDF from a URL.

Navigates to the specified URL using a browser from the pool, waits for JavaScript execution, and generates a PDF of the rendered page.

§Thread Safety

This function is thread-safe and can be called concurrently from multiple threads. The browser pool mutex ensures safe access to shared resources.

§Blocking Behavior

This function blocks the calling thread. In async contexts, wrap it in tokio::task::spawn_blocking, actix_web::web::block, or similar.

§Arguments

  • pool - Reference to the mutex-wrapped browser pool. The mutex is held only briefly during browser checkout; PDF generation occurs outside the lock.
  • request - PDF generation parameters. See PdfFromUrlRequest for details.

§Returns

  • Ok(PdfResponse) - Successfully generated PDF with binary data and metadata
  • Err(PdfServiceError) - Error with details about what went wrong

§Errors

ErrorCauseResolution
InvalidUrlURL is empty or malformedProvide valid HTTP/HTTPS URL
PoolLockFailedMutex poisonedRestart service
BrowserUnavailablePool exhaustedRetry or increase pool size
TabCreationFailedBrowser issueAutomatic recovery
NavigationFailedURL unreachableCheck URL accessibility
NavigationTimeoutPage too slowIncrease timeout or optimize page
PdfGenerationFailedRendering issueSimplify page or check content

§Examples

§Basic Usage

use html2pdf_api::service::{generate_pdf_from_url, PdfFromUrlRequest};

let request = PdfFromUrlRequest {
    url: "https://example.com".to_string(),
    ..Default::default()
};

let response = generate_pdf_from_url(&pool, &request)?;
assert!(response.data.starts_with(b"%PDF-")); // Valid PDF header

§With Custom Options

let request = PdfFromUrlRequest {
    url: "https://example.com/report".to_string(),
    filename: Some("quarterly-report.pdf".to_string()),
    landscape: Some(true),      // Wide tables
    waitsecs: Some(10),         // Complex charts
    download: Some(true),       // Force download
    print_background: Some(true),
};

let response = generate_pdf_from_url(&pool, &request)?;
println!("Generated {} with {} bytes", response.filename, response.size());

§Error Handling

match generate_pdf_from_url(&pool, &request) {
    Ok(pdf) => {
        // Success - use pdf.data
    }
    Err(PdfServiceError::InvalidUrl(msg)) => {
        // Client error - return 400
        eprintln!("Bad URL: {}", msg);
    }
    Err(PdfServiceError::BrowserUnavailable(_)) => {
        // Transient error - retry
        std::thread::sleep(Duration::from_secs(1));
    }
    Err(e) => {
        // Other error
        eprintln!("PDF generation failed: {}", e);
    }
}

§Performance

Typical execution time breakdown for a moderately complex page:

┌────────────────────────────────────────────────────────────────┐
│ Pool lock + browser checkout                          ~1ms    │
│ ├─────────────────────────────────────────────────────────────┤
│ Tab creation                                          ~50ms   │
│ ├─────────────────────────────────────────────────────────────┤
│ Navigation + page load                                ~500ms  │
│ ├─────────────────────────────────────────────────────────────┤
│ JavaScript wait (configurable)                        ~5000ms │
│ ├─────────────────────────────────────────────────────────────┤
│ PDF rendering                                         ~200ms  │
│ ├─────────────────────────────────────────────────────────────┤
│ Tab cleanup                                           ~50ms   │
└────────────────────────────────────────────────────────────────┘
Total: ~5.8 seconds (dominated by JS wait)