diff --git a/src/context/context.ts b/src/context/context.ts index a999385..56533a4 100644 --- a/src/context/context.ts +++ b/src/context/context.ts @@ -90,4 +90,5 @@ export interface Svg2pdfParameters { width?: number height?: number loadExternalStyleSheets?: boolean + onImageError?: (imageUrl: string, error: Error, element: Element) => boolean } diff --git a/src/nodes/image.ts b/src/nodes/image.ts index 9f3da10..3e8a748 100644 --- a/src/nodes/image.ts +++ b/src/nodes/image.ts @@ -41,7 +41,26 @@ export class ImageNode extends GraphicsNode { return } - const { data, format } = await this.imageLoadingPromise + let data + let format + try { + const res = await this.imageLoadingPromise + data = res.data + format = res.format + } catch (e) { + const error = e instanceof Error ? e : new Error(String(e)) + const onImageError = context.svg2pdfParameters?.onImageError + if (onImageError && this.imageUrl) { + const shouldThrow = onImageError(this.imageUrl, error, this.element) + if (shouldThrow === true) { + throw error + } + } + } + + if (!data || !format) { + return + } if (format.indexOf('svg') === 0) { const parser = new DOMParser() @@ -99,9 +118,18 @@ export class ImageNode extends GraphicsNode { imgHeight ) } catch (e) { - typeof console === 'object' && - console.warn && - console.warn(`Could not load image ${this.imageUrl}. \n${e}`) + const error = e instanceof Error ? e : new Error(String(e)) + const onImageError = context.svg2pdfParameters?.onImageError + if (onImageError && this.imageUrl) { + const shouldThrow = onImageError(this.imageUrl, error, this.element) + if (shouldThrow === true) { + throw error + } + } else { + typeof console === 'object' && + console.warn && + console.warn(`Could not load image ${this.imageUrl}. \n${e}`) + } } } } diff --git a/src/svg2pdf.ts b/src/svg2pdf.ts index f805b93..16e1fc6 100644 --- a/src/svg2pdf.ts +++ b/src/svg2pdf.ts @@ -77,4 +77,17 @@ export interface Svg2PdfOptions { width?: number height?: number loadExternalStyleSheets?: boolean + /** + * Optional callback function that is called when an image fails to load. + * If provided, this callback will be invoked with error details instead of + * silently ignoring the error. The callback can decide how to handle the error + * (e.g., throw an exception, log to a custom logging system, or provide fallback behavior). + * + * @param imageUrl - The URL of the image that failed to load + * @param error - The error object describing what went wrong + * @param element - The SVG image element that failed to load + * @returns If the callback returns `true`, the error will be re-thrown to interrupt the rendering process. + * If it returns `false`, the error will be silently ignored and the image will be skipped. + */ + onImageError?: (imageUrl: string, error: Error, element: Element) => boolean } diff --git a/types.d.ts b/types.d.ts index abef38e..ce3444c 100644 --- a/types.d.ts +++ b/types.d.ts @@ -67,4 +67,18 @@ export interface Svg2pdfOptions { * policies are ignored. The default is false. */ loadExternalStyleSheets?: boolean + + /** + * Optional callback function that is called when an image fails to load. + * If provided, this callback will be invoked with error details instead of + * silently ignoring the error. The callback can decide how to handle the error + * (e.g., throw an exception, log to a custom logging system, or provide fallback behavior). + * + * @param imageUrl - The URL of the image that failed to load + * @param error - The error object describing what went wrong + * @param element - The SVG image element that failed to load + * @returns If the callback returns `true`, the error will be re-thrown to interrupt the rendering process. + * If it returns `false`, the error will be silently ignored and the image will be skipped. + */ + onImageError?: (imageUrl: string, error: Error, element: Element) => boolean }