Throwing error in lifecycle hook doesn't stop script from executing

System Information
  • Strapi Version: 3.2.0
  • Operating System: macOS
  • Database: mongodb
  • Node Version: 12.20.1
  • NPM Version: 6.14.12
  • Yarn Version: 1.22.10

Throwing an error in lifecycle hook gets triggered in try catch but the input still saves (it should be prevented) and the error is not showing as a popup in the UI

I can get the error to console.log so the code works but I expect/want it to show the error in the UI and the script to stop so Strapi won’t save the data that triggered the error.
I tried adding return in the catch block, can’t use break or exit, so what else can I do?

module.exports = {
      lifecycles: {
try {
  if(num < 3) {
    throw new Error('Some message');
  } else {
    //do something if not error
  }
} catch (err) {
  console.log(err.name + " " + err.message);
  return;
     }
   }
}

** that is not the code, just more or less the try/catch blocks

Lifecycles can’t stop the Creation/Updating of an entry by using the return inside it. The return in lifecycle just means “I don’t want to modify any data before creation/update”.

In that case, you should throw errors instead of returns in beforeCreate/beforeUpdate lifecycles.

So the correct approach to stop a creation will be:

beforeCreate(data, model) {
         if(data.num < 3) {
               throw new Error('Num is not smaller than 3.'); // throwing errors will STOP the creation.
         }
    },

Also, if you are trying to do simple checks, like check the numbers, you can also define its max/min values directly in Content Manager when editing a Number field.
image

The same applies to Text fields, you can define regex patterns to do validation in Admin before creation:
image

1 Like

Thanks @sunnyson.
I was actually doing that already, but I see my example code snippet was confusing.
What ended up working was moving the code out of the try catch.

Hello @sunnyson, could you help me? I followed your instructions and despite showing a 422 error, the post is still published. Here is the code:

async beforeCreate(params, data) {
      const post = await strapi.query('post').find({ id: params.id });
      if (
        post[0].published_at &&
        (!post[0].subcategories.length || !post[0].categories.length)
      ) {
        throw new Error('Category or subcategory is missing');
      }
    }

if a component is added to an entity, then it continues to save values when an exception/error is triggered. Does anyone know how to prevent this?

I second this – throwing an error results in a crash. Common usecase for beforeCreate() would be to modify the params and perform simple operations.

With the current functionality you need to copy and override the default controller and put the logic there instead, which seems overkill for a lot of use-cases.