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. SeePdfFromUrlRequestfor details.
§Returns
Ok(PdfResponse)- Successfully generated PDF with binary data and metadataErr(PdfServiceError)- Error with details about what went wrong
§Errors
| Error | Cause | Resolution |
|---|---|---|
InvalidUrl | URL is empty or malformed | Provide valid HTTP/HTTPS URL |
PoolLockFailed | Mutex poisoned | Restart service |
BrowserUnavailable | Pool exhausted | Retry or increase pool size |
TabCreationFailed | Browser issue | Automatic recovery |
NavigationFailed | URL unreachable | Check URL accessibility |
NavigationTimeout | Page too slow | Increase timeout or optimize page |
PdfGenerationFailed | Rendering issue | Simplify 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)