-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve errors for invalid IDs in content collections #12892
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'astro': patch | ||
--- | ||
|
||
Added more verbose errors for content collections with invalid IDs. | ||
|
||
Previously, when an entry in a content collection had an ID that wasn't a string, the error would omit the ID entirely. With this change, the error will now explicitly say that the ID has to be a string. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1563,6 +1563,34 @@ export const InvalidContentEntryDataError = { | |||||
hint: 'See https://docs.astro.build/en/guides/content-collections/ for more information on content schemas.', | ||||||
} satisfies ErrorData; | ||||||
|
||||||
/** | ||||||
* @docs | ||||||
* @message | ||||||
* **Example error message:**<br/> | ||||||
* The content loader for the collection **blog** returned an invalid result:<br/> | ||||||
* Content entry `id` must be a string:<br/> | ||||||
* {<br/> | ||||||
* "id": 1,<br/> | ||||||
* "title": "Hello, World!"<br/> | ||||||
* } | ||||||
* @description | ||||||
* A content loader returned an invalid result. | ||||||
* Make sure that the ID of the entry is a string. | ||||||
* See the [Content collections documentation](https://docs.astro.build/en/guides/content-collections/) for more information. | ||||||
*/ | ||||||
export const ContentLoaderReturnsInvalidResult = { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Just an e.g. based on my earlier question. There are probably lots of ways an entry can be invalid, so does it make sense to entirely base this on invalid ID There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See reply on previous change request |
||||||
name: 'ContentLoaderReturnsInvalidResult', | ||||||
title: 'Content loader returns invalid result.', | ||||||
message(collection: string, entry: any, message: string) { | ||||||
return [ | ||||||
`The content loader for the collection **${String(collection)}** returned an invalid result:`, | ||||||
`${message}:`, | ||||||
JSON.stringify(entry, null, 2), | ||||||
].join('\n'); | ||||||
}, | ||||||
hint: 'See https://docs.astro.build/en/guides/content-collections/ for more information on content schemas.', | ||||||
} satisfies ErrorData; | ||||||
|
||||||
/** | ||||||
* @docs | ||||||
* @message | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "@test/content-collections-number-id", | ||
"version": "0.0.0", | ||
"private": true, | ||
"type": "module", | ||
"dependencies": { | ||
"astro": "workspace:*" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { defineCollection, z } from 'astro:content'; | ||
|
||
const data = defineCollection({ | ||
loader: async () => ([ | ||
{ id: 1, title: 'One!' }, | ||
{ id: 2, title: 'Two!' }, | ||
{ id: 3, title: 'Three!' }, | ||
]), | ||
schema: z.object({ | ||
id: z.number(), | ||
title: z.string(), | ||
}), | ||
}); | ||
|
||
export const collections = { | ||
data, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
import { getEntry } from 'astro:content'; | ||
const data = await getEntry('blog', 1); | ||
--- | ||
|
||
{JSON.stringify(data)} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like the title of your PR, if the reason this entry is invalid is only and exactly because of the ID, would it be more helpful to specify this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried keeping the error as agnostic as possible so it can be used for other validation that might be needed in the future. The actual error content does include the following line:
"Property
id
has to be a string"And right below that it shows the entry that caused this error.
Edit: The actual error message is supplied by the validation schema itself, meaning that this error can easily be extended with further error messages for other properties if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just checking on this because I'm totally not sure whether this is how we've handled error messages in the past! I'm not sure we've had one that "means different things" and gets a different message based on exactly what went wrong. Usually it's one particular error, but the dynamic part of the message is e.g. identifying the file name or something like that.
Would love for someone to confirm this! Maybe @ematipico would be in a good position to judge this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah fair enough, didn't know that. Gonna wait for Ema's input then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, we usually want to create specific messages. These objects are also created in our documentation, so users who land on our docs want to know exactly what the error is and how to fix it.
I share the sentiment of reusing shared "code"/"logic", but in this case we need to bend our vision towards DX and provide specific messages to users.
So the main message should be hardcoded in the error itself.