System Information
- Strapi Version: 4.14.5
- Operating System: macos (local environment), debian (docker image based on node:18-slim)
- Database: PostgreSQL
- Node Version: 18.18.2
Hey,
I hope someone can help me with this as I’m scratching my head for few days already. Ive tried looking into documentation, this forum, google search, but I found only scraps regarding custom fields validation.
Basically, in a component called sponsored I have two date fields (start date and end date). I need to validate that if both dates are filled, the start date must be before end date.
I tried to apply the solution from @sofian-io that he posted in this forum post.
So my article lifecycle file looked like this:
import {errors} from "@strapi/utils";
import yup from "yup"
export default {
beforeCreate(event) {
const ctx = strapi.requestContext.get();
const sponsored = ctx.request.body.sponsored;
sponsoredValidation(sponsored);
}
}
function sponsoredValidation(sponsored) {
if (sponsored?.isSponsored) {
if (sponsored.sponsoredEndDate < sponsored.sponsoredStartDate) {
sponsoredErrorMessage("SponsoredStartDate should be before SponsoredEndDate.", sponsored.sponsoredEndDate);
}
}
}
function sponsoredErrorMessage(message, endDate) {
const errorMessage: yup.ValidationError = {
path: 'sponsored.sponsoredEndDate',
message: message,
value: endDate,
name: "Sponsored Validation",
errors: null,
inner: null,
};
throw new errors.YupValidationError(errorMessage)
}
It was running fine when executed from my local environment using npm run develop
The field validation run fine and I got red border on the date field with a Validation message underneath saying “SponsoredStartDate should be before SponsoredEndDate.”
I don’ t get anything logged in console,
and in chrome dev tools I can see request to /content-manager/collection-types/api::article.article/128 with a 400 response and response body
{
"data": null,
"error": {
"status": 400,
"name": "ValidationError",
"message": "SponsoredStartDate should be before SponsoredEndDate.",
"details": {
"errors": [
{
"path": [
"sponsored",
"sponsoredEndDate"
],
"message": "SponsoredStartDate should be before SponsoredEndDate.",
"name": "Sponsored Start Date"
}
]
}
}
}
The same code, deployed to a docker image, in the UI I briefly see an error popup saying “Warning: Internal Server Error” and logged in the console
[2023-11-06 15:31:19.429] error: SponsoredStartDate should be before SponsoredEndDate.
ValidationError: SponsoredStartDate should be before SponsoredEndDate.
at sponsoredErrorMessage (/opt/app/dist/src/api/article/content-types/article/lifecycles.js:44:11)
at sponsoredValidation (/opt/app/dist/src/api/article/content-types/article/lifecycles.js:31:13)
at Object.beforeUpdate (/opt/app/dist/src/api/article/content-types/article/lifecycles.js:22:9)
at modelsLifecyclesSubscriber (/opt/node_modules/@strapi/database/dist/index.js:5877:79)
at Object.run (/opt/node_modules/@strapi/database/dist/index.js:5963:17)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Object.update (/opt/node_modules/@strapi/database/dist/index.js:5078:22)
at async Object.update (/opt/node_modules/@strapi/strapi/dist/services/entity-service/index.js:161:22)
at async Object.<anonymous> (/opt/node_modules/@strapi/strapi/dist/services/entity-service/index.js:295:24)
at async Object.update (/opt/node_modules/@strapi/plugin-i18n/server/services/entity-service-decorator.js:155:19)
in chrome dev tools I can see a see request to /content-manager/collection-types/api::article.article/128 with a 500 response and response body
{
"data": null,
"error": {
"status": 500,
"name": "InternalServerError",
"message": "Internal Server Error"
}
}
Then I thought that maybe lifecycle hook is not the best place to do this. So after some digging I found this blog post and decided to move the validation into a global middleware.
Again everything works fine in local dev environment, but when I execute in docker, I have the same behaviour - 500 response and error logged.
and this is my Dockerfile
# Creating multi-stage build for production
FROM public.ecr.aws/docker/library/node:18-slim as build
RUN apt-get update
RUN apt-get install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev -y
RUN apt-get install python3 -y
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
ARG NODE_ENV=prod
ENV NODE_ENV=${NODE_ENV}
WORKDIR /opt/
COPY code/package.json ./
COPY code/patches/ ./patches/
RUN npm install --production
ENV PATH /opt/node_modules/.bin:$PATH
WORKDIR /opt/app
COPY code/ .
RUN npm run build
# Creating final production image
FROM public.ecr.aws/docker/library/node:18-slim
WORKDIR /opt/
COPY --from=build /opt/node_modules ./node_modules
WORKDIR /opt/app
COPY --from=build /opt/app ./
ENV PATH /opt/node_modules/.bin:$PATH
RUN chown -R node:node /opt/app
USER node
EXPOSE 1337
CMD ["npm", "run", "start"]
I also noticed same with invalid credentials - when I provide invalid credentials on my local environment, the UI validation message will say Invalid credentials. But run from inside docker, I see Internal Server Error and error log in the console saying:
[2023-11-06 15:59:05.419] error: Invalid credentials
ApplicationError: Invalid credentials
at /opt/node_modules/@strapi/admin/server/controllers/authentication.js:36:17
at callback (/opt/node_modules/koa-passport/lib/framework/koa.js:93:25)
at allFailed (/opt/node_modules/passport/lib/middleware/authenticate.js:110:18)
at attempt (/opt/node_modules/passport/lib/middleware/authenticate.js:183:28)
at strategy.fail (/opt/node_modules/passport/lib/middleware/authenticate.js:305:9)
at verified (/opt/node_modules/passport-local/lib/strategy.js:82:30)
at /opt/node_modules/@strapi/admin/server/services/passport/local-strategy.js:21:18
Why would validation error handling behave differently depending on environment? Is there any specific configuration that I need to add/update to make sure it runs correctly on any environment?