From f515b1421afa335b8d6e4491fbe24419df53bfeb Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 19 Dec 2023 11:14:58 -0500 Subject: [PATCH] Descriptive image error (#9352) Co-authored-by: Florian Lefebvre Co-authored-by: Sarah Rainsberger Co-authored-by: Princesseuh <3019731+Princesseuh@users.noreply.github.com> --- .changeset/famous-cars-sell.md | 5 +++ packages/astro/package.json | 2 +- packages/astro/src/assets/build/generate.ts | 38 ++++++++++++++----- packages/astro/src/assets/endpoint/generic.ts | 1 + packages/astro/src/assets/endpoint/node.ts | 1 + packages/astro/src/assets/internal.ts | 2 +- packages/astro/src/core/errors/errors-data.ts | 17 +++++++++ pnpm-lock.yaml | 18 ++++----- 8 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 .changeset/famous-cars-sell.md diff --git a/.changeset/famous-cars-sell.md b/.changeset/famous-cars-sell.md new file mode 100644 index 000000000000..983945b058eb --- /dev/null +++ b/.changeset/famous-cars-sell.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Add a more descriptive error message when image conversion fails diff --git a/packages/astro/package.json b/packages/astro/package.json index 10ee99683759..79ce323f23d4 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -153,7 +153,7 @@ "mime": "^3.0.0", "ora": "^7.0.1", "p-limit": "^5.0.0", - "p-queue": "^7.4.1", + "p-queue": "^8.0.1", "path-to-regexp": "^6.2.1", "preferred-pm": "^3.1.2", "probe-image-size": "^7.2.3", diff --git a/packages/astro/src/assets/build/generate.ts b/packages/astro/src/assets/build/generate.ts index 0776dc2d6911..4ee210ec3037 100644 --- a/packages/astro/src/assets/build/generate.ts +++ b/packages/astro/src/assets/build/generate.ts @@ -6,6 +6,8 @@ import type { AstroConfig } from '../../@types/astro.js'; import type { BuildPipeline } from '../../core/build/buildPipeline.js'; import { getOutDirWithinCwd } from '../../core/build/common.js'; import { getTimeStat } from '../../core/build/util.js'; +import { AstroError } from '../../core/errors/errors.js'; +import { AstroErrorData } from '../../core/errors/index.js'; import type { Logger } from '../../core/logger/core.js'; import { isRemotePath, prependForwardSlash } from '../../core/path.js'; import { isServerLikeOutput } from '../../prerender/utils.js'; @@ -103,9 +105,11 @@ export async function generateImagesForPath( const originalImageData = await loadImage(originalFilePath, env); for (const [_, transform] of transformsAndPath.transforms) { - queue.add(async () => - generateImage(originalImageData, transform.finalPath, transform.transform) - ); + await queue + .add(async () => generateImage(originalImageData, transform.finalPath, transform.transform)) + .catch((e) => { + throw e; + }); } // In SSR, we cannot know if an image is referenced in a server-rendered page, so we can't delete anything @@ -207,13 +211,27 @@ export async function generateImagesForPath( }; const imageService = (await getConfiguredImageService()) as LocalImageService; - resultData.data = ( - await imageService.transform( - originalImage.data, - { ...options, src: originalImagePath }, - env.imageConfig - ) - ).data; + + try { + resultData.data = ( + await imageService.transform( + originalImage.data, + { ...options, src: originalImagePath }, + env.imageConfig + ) + ).data; + } catch (e) { + const error = new AstroError( + { + ...AstroErrorData.CouldNotTransformImage, + message: AstroErrorData.CouldNotTransformImage.message(originalFilePath), + }, + undefined, + { cause: e } + ); + + throw error; + } try { // Write the cache entry diff --git a/packages/astro/src/assets/endpoint/generic.ts b/packages/astro/src/assets/endpoint/generic.ts index 5243a7e7c2e7..60845dfd9d7e 100644 --- a/packages/astro/src/assets/endpoint/generic.ts +++ b/packages/astro/src/assets/endpoint/generic.ts @@ -71,6 +71,7 @@ export const GET: APIRoute = async ({ request }) => { }, }); } catch (err: unknown) { + console.error('Could not process image request:', err); return new Response(`Server Error: ${err}`, { status: 500 }); } }; diff --git a/packages/astro/src/assets/endpoint/node.ts b/packages/astro/src/assets/endpoint/node.ts index 604d75d255c5..8c85e78be474 100644 --- a/packages/astro/src/assets/endpoint/node.ts +++ b/packages/astro/src/assets/endpoint/node.ts @@ -89,6 +89,7 @@ export const GET: APIRoute = async ({ request }) => { }, }); } catch (err: unknown) { + console.error('Could not process image request:', err); return new Response(`Server Error: ${err}`, { status: 500 }); } }; diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts index 2098e0d754a7..f6b8e40dc26e 100644 --- a/packages/astro/src/assets/internal.ts +++ b/packages/astro/src/assets/internal.ts @@ -17,7 +17,7 @@ export async function getConfiguredImageService(): Promise { 'virtual:image-service' ).catch((e) => { const error = new AstroError(AstroErrorData.InvalidImageService); - (error as any).cause = e; + error.cause = e; throw error; }); diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 1e00e47ace6d..57176e5a3d0a 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -706,6 +706,23 @@ export const MarkdownImageNotFound = { hint: 'This is often caused by a typo in the image path. Please make sure the file exists, and is spelled correctly.', } satisfies ErrorData; +/** + * @docs + * @see + * - [Images](https://docs.astro.build/en/guides/images/) + * @description + * Astro could not transform one of your images. Often, this is caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue. + * + * Depending on the image service you are using, the stack trace may contain more information on the specific error encountered. + */ +export const CouldNotTransformImage = { + name: 'CouldNotTransformImage', + title: 'Could not transform image.', + message: (imagePath: string) => + `Could not transform image \`${imagePath}\`. See the stack trace for more information.`, + hint: 'This is often caused by a corrupted or malformed image. Re-exporting the image from your image editor may fix this issue.', +} satisfies ErrorData; + /** * @docs * @description diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ac3873c8215..e70e353ad1aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -596,8 +596,8 @@ importers: specifier: ^5.0.0 version: 5.0.0 p-queue: - specifier: ^7.4.1 - version: 7.4.1 + specifier: ^8.0.1 + version: 8.0.1 path-to-regexp: specifier: ^6.2.1 version: 6.2.1 @@ -12964,17 +12964,17 @@ packages: aggregate-error: 4.0.1 dev: true - /p-queue@7.4.1: - resolution: {integrity: sha512-vRpMXmIkYF2/1hLBKisKeVYJZ8S2tZ0zEAmIJgdVKP2nq0nh4qCdf8bgw+ZgKrkh71AOCaqzwbJJk1WtdcF3VA==} - engines: {node: '>=12'} + /p-queue@8.0.1: + resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} + engines: {node: '>=18'} dependencies: eventemitter3: 5.0.1 - p-timeout: 5.1.0 + p-timeout: 6.1.2 dev: false - /p-timeout@5.1.0: - resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} - engines: {node: '>=12'} + /p-timeout@6.1.2: + resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} + engines: {node: '>=14.16'} dev: false /p-try@2.2.0: