Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot find module 'next/dist/next-server/server/api-utils.js' from 'node_modules/next-test-api-route-handler/dist/index.js' #320

Closed
willnix86 opened this issue Sep 1, 2021 · 7 comments
Labels
bug Something isn't working

Comments

@willnix86
Copy link

The problem

Using Next 11.0.1 and NTARH 2.0.1, when running tests I receive the following error:

Cannot find module 'next/dist/next-server/server/api-utils.js' from 'node_modules/next-test-api-route-handler/dist/index.js'

If I look in the next node_modules folder, the correct path is 'next/dist/server/api-utils.js'

@willnix86 willnix86 added the bug Something isn't working label Sep 1, 2021
@Xunnamius
Copy link
Owner

Ah, yeah, the NextJS devs have the api-utils in four different locations across several versions 😅. This should be accounted for in the latest version of NTARH (v2.2.1). If you are able to update, does the problem go away?

@willnix86
Copy link
Author

willnix86 commented Sep 1, 2021 via email

@Xunnamius
Copy link
Owner

Just to be sure: I meant only update NTARH, not NextJS. The latest NTARH should work with the older NextJS v11.0.x (integration tests are passing at least).

@willnix86
Copy link
Author

willnix86 commented Sep 2, 2021

So, updating to 2.2.1 gives me this error:

TypeError [ERR_INVALID_ARG_TYPE]: The "string" argument must be of type string or an instance of Buffer or ArrayBuffer. Received undefined

  at ServerResponse.apiRes.end (node_modules/next/server/api-utils.ts:77:33)
  at onerror (node_modules/next-connect/dist/index.cjs:4:47)
  at node_modules/next-connect/dist/index.cjs:16:16
  at apiResolver (node_modules/next/dist/server/api-utils.js:101:9)

@Xunnamius
Copy link
Owner

Xunnamius commented Sep 2, 2021

Interesting, this seems like the NextJS resolver function itself might have a problem with your handler, since NTARH doesn't call res.end (only your handler and the resolver do).

First, does your handler code run in NextJS normally without errors?

Second, can you show me the code around your usage of the testApiHandler function and the handler you're testing? Or better yet, if you can spin up a tiny dummy repo that reproduces your error, I can pinpoint the problem 🙂

@willnix86
Copy link
Author

willnix86 commented Sep 14, 2021

Of course! So, here's an example of how i use testApiHandler:

it("should fail if no parameters are passed", async () => {
await testApiHandler({
handler: storeMapHandler,
test: async ({ fetch }) => {
const res = await fetch({ method: "POST", headers, body: null });
expect(res.status).toBe(400);
expect(
((await res.json()) as FailedResponse).error.includes(
"Missing or Empty"
)
).toBe(true);
},
});
});

And here's the code for the handler itself:

import { VarBinary, MAX, PreparedStatement } from "mssql";
import nextConnect from "next-connect";
import { NextApiResponse } from "next";
import sessionMiddleware from "../middlewares/session";
import dbUtils from "../../../utils/db";
import { createBufferFromJSON } from "utils/helpers";
import { SessionedNextApiRequest } from "types/auth.types";

const handler = nextConnect();
handler.use(sessionMiddleware);

handler.post(
async (req: SessionedNextApiRequest, res: NextApiResponse, next) => {
if (req.headers["content-type"] !== "application/json") {
res.status(400).json({
error: Content-Type must be JSON,
});
next(res);
}

const { id, mapProps } = req.body;

interface Body {
  [key: string]: any;
}
const body: Body = {
  user_id: req.user_id,
  map_id: id,
  map_properties: mapProps,
};

const requiredFields = ["user_id", "map_id", "map_properties"];
requiredFields.forEach((field) => {
  if (!body.hasOwnProperty(field) || field === "" || !body[field]) {
    res.status(400).json({ error: `Missing or Empty ${field}` });
    next(res);
  }
});

const { map_id, user_id, map_properties } = body;

try {
  await dbUtils.connect();
  await dbUtils.executePreparedStatementFunction(
    async () =>
      await executeStoreMap(map_id, Number(user_id), map_properties)
  );
  res.status(200).end();
  next(res);
} catch (error) {
  res.status(400).json({ error });
  next(res);
}
next(res);

}
);

// There's no way for us to convert Strings to SQL Blobs ourselves, so have to use a PreparedStatement here.
const executeStoreMap = async (
map_id: string,
user_id: number,
map_properties: string
) => {
const mapProps = createBufferFromJSON(map_properties);
const statement = new PreparedStatement(dbUtils.db);
statement.input("mapProps", VarBinary(MAX));
await statement.prepare(INSERT INTO ${process.env.SHARED_MAPS_TABLE_NAME}(id, user_id, map_properties) VALUES('${map_id}', ${user_id}, @mapProps));
await statement.execute({ mapProps });
await statement.unprepare();
};

export default handler;

@Xunnamius
Copy link
Owner

Closing this in favor of #378. If this is a different issue and/or this wasn't solved by upgrading to next-test-api-route-handler@2.2.1, let me know and I'll reopen this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants