Custom controller created on server showing 404 not found but working in local

System Information
  • 4.0:
  • Mac OS:
  • Database:
  • Node Version:
  • NPM Version:
  • Yarn Version:
const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController(
  "api::application.application",
  ({ strapi }) => ({
    async getFormDetailsBasedOnApplicationAction(ctx) {
      try {
        /**
         * Queries the RCMP collection type
         * using the Entity Service APIs
         * to retrieve information about the documents
         */
        const user = ctx.state.user;
        if (!user) {
          return ctx.badRequest(null, [
            { messages: [{ id: "No authorization header was found" }] },
          ]);
        }

        const entries = await strapi.entityService.findMany(
          "api::application.application",
          ctx.query
        );

        const finalEntries = [];
        Promise.all(
          entries.map(async (entry) => {
            let formData = {};
            if (entry && entry.formType === "RCMP") {
              formData = await strapi.entityService.findOne(
                "api::rcmp-form.rcmp-form",
                entry.orderId,
                {
                  populate: { document: true },
                }
              );
              finalEntries.push({ ...entry, formData });
            } else if (entry && entry.formType === "FBI_APOSTILLE") {
              formData = await strapi.entityService.findOne(
                "api::fbi-apostille-form.fbi-apostille-form",
                entry.orderId,
                {
                  populate: { document: true },
                }
              );
              finalEntries.push({ ...entry, formData });
            }
          })
        )
          .then((results) => {
            ctx.body = {
              data: finalEntries,
            };

            return ctx;
          })
          .catch((e) => {
            ctx.body = e;

            return ctx;
            // Handle errors here
          });
      } catch (err) {
        ctx.body = err;

        return ctx;
      }
    },
  })
);

Am i returning the data correctly? Or do I have to sanitize the output?

Hey @vinikatyal,

It seems okay with the return method. You can also use ctx.send({}) instead of return/ctx.body.

Can you show me the console error?

No errors just below message:

{
    "data": null,
    "error": {
        "status": 404,
        "name": "NotFoundError",
        "message": "Not Found",
        "details": {}
    }
}

Have you given roles permission to the custom created API route?

Yes I have given, it works on my local gets all the data

But it doesn’t work on live server, right? Double check everything on live server too.

yes double checked my routing is as below:

Hmm, that’s odd. Can you compare the whole Api url for both local and live server, see if anything’s wrong with the URL.

Also please adjust you route file code like below:

//.src/api/application/routes/application.js
'use strict';
const { createCoreRouter } = require('@strapi/strapi').factories;
const defaultRouter = createCoreRouter('api::application.application');

const customRouter = (innerRouter, extraRoutes = []) => {
  let routes;
  return {
    get prefix() {
      return innerRouter.prefix;
    },
    get routes() {
      if (!routes) routes = innerRouter.routes.concat(extraRoutes);
      return routes;
    },
  };
};

const myExtraRoutes = [
  {
    method: 'GET',
    path:'/application-details',
    handler:'api::application.application.getFormDetailsBasedOnApplicationAction'
  }
];

module.exports = customRouter(defaultRouter, myExtraRoutes);

I am sure this will work properly at each places.

Tried this did not work

"use strict";

/**
 * application controller
 */

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController(
  "api::application.application",
  ({ strapi }) => ({
    async getFormDetailsBasedOnApplicationAction(ctx) {
      try {
        /**
         * Queries the RCMP collection type
         * using the Entity Service APIs
         * to retrieve information about the documents
         */
        const user = ctx.state.user;
        if (!user) {
          return ctx.badRequest(null, [
            { messages: [{ id: "No authorization header was found" }] },
          ]);
        }

        const entries = await strapi.entityService.findMany(
          "api::application.application",
          ctx.query
        );

        const finalEntries = [];
        Promise.all(
          entries.map(async (entry) => {
            let formData = {};
            if (entry && entry.formType === "RCMP") {
              formData = await strapi.entityService.findOne(
                "api::rcmp-form.rcmp-form",
                entry.orderId,
                {
                  populate: { document: true },
                }
              );
              finalEntries.push({ ...entry, formData });
            } else if (entry && entry.formType === "FBI_APOSTILLE") {
              formData = await strapi.entityService.findOne(
                "api::fbi-apostille-form.fbi-apostille-form",
                entry.orderId,
                {
                  populate: { document: true },
                }
              );
              finalEntries.push({ ...entry, formData });
            }
          })
        )
          .then(async (results) => {
            const sanitizedEntries = await this.sanitizeOutput(
              finalEntries,
              ctx
            );

            console.log(sanitizedEntries)

            return ctx.send(this.transformResponse(sanitizedEntries));
          })
          .catch((e) => {
            ctx.body = e;
            return ctx.send(this.transformResponse(e));
            // Handle errors here
          });
      } catch (err) {
        ctx.body = err;

        return ctx.send(this.transformResponse(err));
      }
    },
  })
);
**strong text**

Its weird because its consoling the output of sanitized entries on the server as well

Server outputs response but router says 404 not found

Okay. So there’s nothing wrong with the route call but something wrong with your Promise.all() code block.

I see you are using finalEntries.push() instead or returning value under the Promise.all(). Before the values are pushed in to the finalEntries the API just run off. Meaning, Api is executed successfully and is not awaiting for finalEntries values in response.

I think that might be the culprit :thinking:

Can you test it by replacing the below code with your Promise code block:

const finalEntries = Promise.all(entries.map(async (entry) => {
  let formData = {};
  let responseData = {};
  if (entry && entry.formType === "RCMP") {
    formData = await strapi.entityService.findOne("api::rcmp-form.rcmp-form", entry.orderId, {
      populate: { document: true },
    });
  } else if (entry && entry.formType === "FBI_APOSTILLE") {
    formData = await strapi.entityService.findOne("api::fbi-apostille-form.fbi-apostille-form", entry.orderId, {
      populate: { document: true },
    });
  }
  responseData = { ...entry, formData };
}))
.catch((e) => {
  ctx.body = e;
  return ctx;
});
console.log(finalEntries) // Check this with your old code and then check it with the above code

I hope this may work as I use the same concept in my project.

Where exactly? should this be placed i dont see it returning the values

I understand what you are saying its actually not resolving the promise just going outside and trying to find a response but then it doesnt so it causes a 404 error

Yes correct. That’s what I was trying you to explain and that is why I shared you a different code.

Check my code, I have assigned return values from inside of the whole promise to finalEntries variable. Try debugging it using console.log().

Then send it to the api response via
ctx.body = finalEntries; OR ctx.send({ data: finalEntries })

Shows above on server

@vinikatyal I have to check it myself by creating a demo in my local and the following code worked for me.

The route url:

The controller function:

Output:

1 Like

Thanks so much really appreciate your replies

2 Likes

@Shekhar thank you for your help. :slightly_smiling_face:

2 Likes