feat: add missing translations for hardcoded API error messages#16722
Draft
joan-teriihoania wants to merge 2 commits into
Draft
feat: add missing translations for hardcoded API error messages#16722joan-teriihoania wants to merge 2 commits into
joan-teriihoania wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
I am unsure why there were missing translation keys, or why some keys were created but not used. I assumed it was missed or forgotten during implementation. I've created this PR in case it was. Do let me know! This is my first contribution!
This implementation addresses some of the lack in internationalised error messages in Payload CMS by replacing hardcoded English error strings with translation keys. Previously, API errors were thrown with static English text, even if some had translations available. This made the CMS less accessible to non-English speaking users and limited its global reach. After a quick look at the codebase, I found 73 occurrences of hardcoded error messages across various packages, including core Payload, plugins, storage adapters, and database adapters. While I only needed a subset translated, I elected to translate all of them for consistency and to future-proof the codebase.
All API errors now follow this pattern:
This uses the payload request's
tfunction for translation when available, and falls back to the original English string if not to ensure that all errors are translatable without breaking existing functionality. And to make use of the existing language detection and infrastructure.I targeted only hardcoded error strings thrown in an
APIErrorsince those are, conceptually, designed to be displayed to the users, and thus should be localised when possible.Changes
In total, there were 73 occurences of hardcoded error message strings throwing an
APIError. Out of those, some strings already had a key in the translation files, but simply didn't use it. And others didn't have translation keys and thus needed to be added. Of the latter, there were 46 new translation keys added topackages/translations/src/languages/*.tsin theerrornamespace:actionWillLockoutPreset- "This action will lock you out of this preset."authenticationRequiredForExport- "User authentication is required to create exports."userRequiredForImport- "User is required for import operations"unauthorized- "Unauthorized" (already existed, now used in more places)attachmentContentInvalid- "Attachment content must be a string or a buffer"attachmentMissingContentAndPath- "Attachment is missing both content and path"attachmentMissingFilename- "Attachment is missing filename"expectedResponseFromUploadHandler- "Expected response from the upload handler."failedToFetchFromURL- "Failed to fetch the file from the provided URL."filenameRequired- "A file name is required."invalidFilename- "Invalid filename"invalidFileURL- "Invalid file url"noFileDataForImport- "No file data provided for import"pastingFromURLNotEnabled- "Pasting from URL is not enabled for this collection."redirectTargetNotAllowed- "Redirect target is not allowed."requestNotEligibleForFileUpload- "Request is not eligible for file upload"tooManyRedirects- "Too many redirects."uploadConfigHandlersMissing- "uploadConfig.handlers is not present for {{collection}}"uploadthingUnknownError- "Error uploading file with uploadthing: Unknown error"urlNotAllowed- "The provided URL is not allowed."validURLRequired- "A valid URL string is required."busboyMultipartError- "Busboy error parsing multipart request"collectionSlugRequired- "Collection slug is required"contentTypeExpectedJSON- "Content-Type expected to be application/json"eitherCollectionOrGlobalRequired- "Either collection or globalSlug must be passed."fieldMustBeSpecified- "field must be specified"fieldsNotInitialized- "Fields are not initialized."invalidJSON- "Invalid JSON"invalidJSONFormat- "Invalid JSON format"joinFieldsNotAllowedInArraysBlocksOrGlobals- "Join fields cannot be added to arrays, blocks or globals."missingIDOfVersionToRestore- "Missing ID of version to restore."noConnectionToDatabase- "beginTransaction called while no connection to the database exists"noPayloadProvided- "No payload was provided"notSupported- "Not supported"orderableJoinsMustTargetSingleCollection- "Orderable joins must target a single collection"relationshipFieldNotFound- "Relationship field was not found"relationshipNotFound- "Relationship was not found"requestDataRequired- "Request data is required."requestURLMissing- "Request URL is missing."somethingWentWrong- "Something went wrong."unexpectedArrayCollectionSlug- "Unexpected array of collectionSlug, parent must be provided"unreachable- "Unreachable"vercelBlobUploadError- "storage-vercel-blob client upload route error"Files intentionally not updated
The following files were found during the search but were not updated because they lack access to the
PayloadRequestobject or are test/example files. By their very nature as tests, examples, or utilities, they are not always able to access the request object and itstfunction, and thus would require a more complex refactor to support internationalization.Test Files
test/plugin-sentry/config.tstest/uploads/collections/BulkUploadsHookError/index.tstest/versions/collections/DraftsWithChangeHook.tstest/versions/collections/ErrorOnUnpublish.tstest/collections-rest/config.tspackages/payload/src/utilities/formatErrors.spec.tsCodemod/Example Files
packages/codemod/src/transforms/migrate-aliased-exports/merge.input.tspackages/codemod/src/transforms/migrate-aliased-exports/merge.output.tsexamples/multi-tenant/src/collections/Users/endpoints/externalUsersLogin.tsLow-Level utilities
packages/payload/src/utilities/sanitizeFilename.tspackages/payload/src/fields/config/sanitizeJoinField.tspackages/ui/src/utilities/buildTableState.tspackages/db-mongodb/src/transactions/beginTransaction.tspackages/db-mongodb/src/queries/getBuildQueryPlugin.tspackages/db-mongodb/src/queries/buildSearchParams.tspackages/drizzle/src/queries/getTableColumnFromPath.tspackages/email-resend/src/index.tspackages/payload/src/uploads/fetchAPI-multipart/index.tspackages/payload/src/uploads/fetchAPI-multipart/processMultipart.tspackages/payload/src/database/getLocalizedPaths.tspackages/storage-uploadthing/src/uploadFile.tsStats for the nerds
Next steps
There are two steps that could follow this implementation, or that other people could add on it: 1) generating translations for the new keys in other languages, and 2) refactoring the files that were intentionally not updated to also support i18n.
I know that we have the option to use
pnpm run translateNewKeyswith anOPENAI_KEYbut I do not have that available, and even then I would be severely limited. If someone is able to generate translations for the new keys, that would be a great help. I've added the keys using Sonnet 4.5, but I can't be sure of the quality.As for the remaining files, I'm not sure what to do with them. I've elected to not update them, but do let me know what you think.
Aditionnally, I am planning on making the same PR on the
3.xbranch. Since I don't believe there were any huge changes made between v3 and v4 on internationalisation, I assume that "porting" these diffs to v3 would be easy enough and would require minimal effort.