Upstream payloadcms/payload state of the touched files before e34ea0b1e0

This commit is contained in:
upstream committed 2026-10-17 03:33:29 +02:00
commit e3da300e8e
1 file changed
+93
@@ -0,0 +1,93 @@
import type { TFunction } from '@payloadcms/translations'
import { en } from '@payloadcms/translations/languages/en'
import type { LabelFunction, StaticLabel } from '../config/types.js'
import type { PayloadRequest } from '../types/index.js'
import { httpStatus } from '../utilities/httpStatus.js'
import { APIError } from './APIError.js'
/** @deprecated Use `instanceof ValidationError` instead of name comparison. */
export const ValidationErrorName = 'ValidationError'
export type ValidationFieldError = {
/** Configured field label, when available. */
label?: LabelFunction | StaticLabel
/** Locale for a localized validation pass. Omitted for non-localized validation. */
locale?: string
/** Error message to display for this field. */
message: string
/** Dot-separated path to the invalid field. */
path: string
/** Database table associated with the invalid field, when applicable. */
tableName?: string
}
export class ValidationError extends APIError<{
collection?: string
errors: ValidationFieldError[]
global?: string
}> {
constructor(
results: {
collection?: string
errors: ValidationFieldError[]
global?: string
id?: number | string
/**
* req needs to be passed through (if you have one) in order to resolve label functions that may be part of the errors array
*/
req?: Partial<PayloadRequest>
},
t?: TFunction,
) {
const message = t
? t('error:followingFieldsInvalid', { count: results.errors.length })
: results.errors.length === 1
? en.translations.error.followingFieldsInvalid_one
: en.translations.error.followingFieldsInvalid_other
const req = results.req
// delete to avoid logging the whole req
delete results['req']
const locales = results.errors
.map((fieldError) => fieldError.locale)
.filter((locale): locale is string => Boolean(locale))
const spansMultipleLocales = new Set(locales).size > 1
super(
`${message} ${results.errors
.map((f) => {
const localePrefix = spansMultipleLocales && f.locale ? `[${f.locale}] ` : ''
if (f.label) {
if (typeof f.label === 'function') {
if (!req || !req.i18n || !req.t) {
return `${localePrefix}${f.path}`
}
return `${localePrefix}${f.label({ i18n: req.i18n, t: req.t })}`
}
if (typeof f.label === 'object') {
if (req?.i18n?.language) {
return `${localePrefix}${f.label[req.i18n.language]}`
}
return `${localePrefix}${f.label[Object.keys(f.label)[0]!]}`
}
return `${localePrefix}${f.label}`
}
return `${localePrefix}${f.path}`
})
.join(', ')}`,
httpStatus.BAD_REQUEST,
results,
)
this.name = 'ValidationError'
}
}