summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/slow-mirrors-provide.md5
-rw-r--r--packages/astro/src/assets/internal.ts4
-rw-r--r--packages/astro/src/assets/services/service.ts15
-rw-r--r--packages/astro/src/core/errors/dev/utils.ts12
-rw-r--r--packages/astro/src/core/errors/errors-data.ts24
-rw-r--r--packages/astro/src/core/errors/overlay.ts4
6 files changed, 43 insertions, 21 deletions
diff --git a/.changeset/slow-mirrors-provide.md b/.changeset/slow-mirrors-provide.md
new file mode 100644
index 000000000..768b6106d
--- /dev/null
+++ b/.changeset/slow-mirrors-provide.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Improved error messages around `astro:assets`
diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts
index dd5e427f6..1a266c07a 100644
--- a/packages/astro/src/assets/internal.ts
+++ b/packages/astro/src/assets/internal.ts
@@ -77,12 +77,12 @@ export async function getImage(
const service = await getConfiguredImageService();
- // If the user inlined an import, something fairly common especially in MDX, await it for them
+ // If the user inlined an import, something fairly common especially in MDX, or passed a function that returns an Image, await it for them
const resolvedOptions: ImageTransform = {
...options,
src:
typeof options.src === 'object' && 'then' in options.src
- ? (await options.src).default
+ ? (await options.src).default ?? (await options.src)
: options.src,
};
diff --git a/packages/astro/src/assets/services/service.ts b/packages/astro/src/assets/services/service.ts
index 5af4a898b..69894aa0c 100644
--- a/packages/astro/src/assets/services/service.ts
+++ b/packages/astro/src/assets/services/service.ts
@@ -1,6 +1,6 @@
import type { AstroConfig } from '../../@types/astro.js';
import { AstroError, AstroErrorData } from '../../core/errors/index.js';
-import { joinPaths } from '../../core/path.js';
+import { isRemotePath, joinPaths } from '../../core/path.js';
import { VALID_SUPPORTED_FORMATS } from '../consts.js';
import { isESMImportedImage, isRemoteAllowed } from '../internal.js';
import type { ImageOutputFormat, ImageTransform } from '../types.js';
@@ -126,13 +126,20 @@ export const baseService: Omit<LocalImageService, 'transform'> = {
if (!options.src || (typeof options.src !== 'string' && typeof options.src !== 'object')) {
throw new AstroError({
...AstroErrorData.ExpectedImage,
- message: AstroErrorData.ExpectedImage.message(JSON.stringify(options.src)),
+ message: AstroErrorData.ExpectedImage.message(
+ JSON.stringify(options.src),
+ typeof options.src,
+ JSON.stringify(options, (_, v) => (v === undefined ? null : v))
+ ),
});
}
if (!isESMImportedImage(options.src)) {
- // User passed an `/@fs/` path instead of the full image.
- if (options.src.startsWith('/@fs/')) {
+ // User passed an `/@fs/` path or a filesystem path instead of the full image.
+ if (
+ options.src.startsWith('/@fs/') ||
+ (!isRemotePath(options.src) && !options.src.startsWith('/'))
+ ) {
throw new AstroError({
...AstroErrorData.LocalImageUsedWrongly,
message: AstroErrorData.LocalImageUsedWrongly.message(options.src),
diff --git a/packages/astro/src/core/errors/dev/utils.ts b/packages/astro/src/core/errors/dev/utils.ts
index 837b52fde..fd69b74db 100644
--- a/packages/astro/src/core/errors/dev/utils.ts
+++ b/packages/astro/src/core/errors/dev/utils.ts
@@ -227,21 +227,21 @@ export function getDocsForError(err: ErrorWithMetadata): string | undefined {
* Render a subset of Markdown to HTML or a CLI output
*/
export function renderErrorMarkdown(markdown: string, target: 'html' | 'cli') {
- const linkRegex = /\[(.+)\]\((.+)\)/gm;
+ const linkRegex = /\[([^\[]+)\]\((.*)\)/gm;
const boldRegex = /\*\*(.+)\*\*/gm;
- const urlRegex = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])/gim;
+ const urlRegex = / (\b(https?|ftp):\/\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])/gim;
const codeRegex = /`([^`]+)`/gim;
if (target === 'html') {
return escape(markdown)
.replace(linkRegex, `<a href="$2" target="_blank">$1</a>`)
.replace(boldRegex, '<b>$1</b>')
- .replace(urlRegex, ' <a href="$1" target="_blank">$1</a> ')
+ .replace(urlRegex, ' <a href="$1" target="_blank">$1</a>')
.replace(codeRegex, '<code>$1</code>');
} else {
return markdown
- .replace(linkRegex, (fullMatch, m1, m2) => `${bold(m1)} ${underline(m2)}`)
- .replace(urlRegex, (fullMatch) => ` ${underline(fullMatch.trim())} `)
- .replace(boldRegex, (fullMatch, m1) => `${bold(m1)}`);
+ .replace(linkRegex, (_, m1, m2) => `${bold(m1)} ${underline(m2)}`)
+ .replace(urlRegex, (fullMatch) => ` ${underline(fullMatch.trim())}`)
+ .replace(boldRegex, (_, m1) => `${bold(m1)}`);
}
}
diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts
index d63fc8852..1f336e5f8 100644
--- a/packages/astro/src/core/errors/errors-data.ts
+++ b/packages/astro/src/core/errors/errors-data.ts
@@ -594,9 +594,9 @@ export const PrerenderDynamicEndpointPathCollide = {
export const ExpectedImage = {
name: 'ExpectedImage',
title: 'Expected src to be an image.',
- message: (options: string) =>
- `Expected \`src\` property to be either an ESM imported image or a string with the path of a remote image. Received \`${options}\`.`,
- hint: 'This error can often happen because of a wrong path. Make sure the path to your image is correct.',
+ message: (src: string, typeofOptions: string, fullOptions: string) =>
+ `Expected \`src\` property for \`getImage\` or \`<Image />\` to be either an ESM imported image or a string with the path of a remote image. Received \`${src}\` (type: \`${typeofOptions}\`).\n\nFull serialized options received: \`${fullOptions}\`.`,
+ hint: "This error can often happen because of a wrong path. Make sure the path to your image is correct. If you're passing an async function, make sure to call and await it.",
} satisfies ErrorData;
/**
* @docs
@@ -712,12 +712,15 @@ export const LocalsNotAnObject = {
'`locals` can only be assigned to an object. Other values like numbers, strings, etc. are not accepted.',
hint: 'If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`.',
} satisfies ErrorData;
+
/**
* @docs
* @see
* - [Images](https://docs.astro.build/en/guides/images/)
* @description
- * When using the default image services, `Image`'s and `getImage`'s `src` parameter must be either an imported image or an URL, it cannot be a filepath.
+ * When using the default image services, `Image`'s and `getImage`'s `src` parameter must be either an imported image or an URL, it cannot be a string of a filepath.
+ *
+ * For local images from content collections, you can use the [image() schema helper](https://docs.astro.build/en/guides/images/#images-in-content-collections) to resolve the images.
*
* ```astro
* ---
@@ -728,15 +731,22 @@ export const LocalsNotAnObject = {
* <!-- GOOD: `src` is the full imported image. -->
* <Image src={myImage} alt="Cool image" />
*
- * <!-- BAD: `src` is an image's `src` path instead of the full image. -->
+ * <!-- GOOD: `src` is a URL. -->
+ * <Image src="https://example.com/my_image.png" alt="Cool image" />
+ *
+ * <!-- BAD: `src` is an image's `src` path instead of the full image object. -->
* <Image src={myImage.src} alt="Cool image" />
+ *
+ * <!-- BAD: `src` is a string filepath. -->
+ * <Image src="../my_image.png" alt="Cool image" />
* ```
*/
export const LocalImageUsedWrongly = {
name: 'LocalImageUsedWrongly',
- title: 'ESM imported images must be passed as-is.',
+ title: 'Local images must be imported.',
message: (imageFilePath: string) =>
- `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a filepath. Received \`${imageFilePath}\`.`,
+ `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a string filepath. Received \`${imageFilePath}\`.`,
+ hint: 'If you want to use an image from your `src` folder, you need to either import it or if the image is coming from a content collection, use the [image() schema helper](https://docs.astro.build/en/guides/images/#images-in-content-collections) See https://docs.astro.build/en/guides/images/#src-required for more information on the `src` property.',
} satisfies ErrorData;
/**
diff --git a/packages/astro/src/core/errors/overlay.ts b/packages/astro/src/core/errors/overlay.ts
index 5a24f898a..1ee6fc9d2 100644
--- a/packages/astro/src/core/errors/overlay.ts
+++ b/packages/astro/src/core/errors/overlay.ts
@@ -336,7 +336,7 @@ const style = /* css */ `
#message-content,
#hint-content {
white-space: pre-wrap;
- line-height: 24px;
+ line-height: 26px;
flex-grow: 1;
}
@@ -369,7 +369,7 @@ const style = /* css */ `
#message-hints code {
font-family: var(--font-monospace);
background-color: var(--border);
- padding: 4px;
+ padding: 2px 4px;
border-radius: var(--roundiness);
white-space: nowrap;
}