Minimal Sveltekit + pg integration fails with "status" error - postgresql

I'm trying to get Postgres working with sveltekit and a very minimal example is giving me issues. This is probably a configuration thing but the error I'm getting back from sveltekit makes no sense to me.
I start by installing a new project:
npm create svelte#latest my-testapp
Then I install "pg" to get Postgres pooling:
npm i pg
Then I add a page under src/lib/db.js:
import { Client, Pool } from 'pg';
const pool = new Pool({
user: 'xxx',
host: 'xxx',
database: 'xxx',
password: 'xxx',
port: 5432,
})
export const connectToDB = async () => await pool.connect();
Finally I add src/hooks.server.js to give me access to the pool within routes:
import { connectToDB } from '$lib/db';
export const handle = async ({event, resolve}) => {
const dbconn = await connectToDB();
event.locals = { dbconn };
const response = await resolve(event);
dbconn.release();
}
The server fails to compile with a couple of these errors:
Cannot read properties of undefined (reading 'status')
TypeError: Cannot read properties of undefined (reading 'status')
at respond (file:///C:/Users/user/code/svelte/my-testapp/node_modules/#sveltejs/kit/src/runtime/server/index.js:314:16)
at async file:///C:/Users/user/code/svelte/my-testapp/node_modules/#sveltejs/kit/src/exports/vite/dev/index.js:406:22
Not sure where "status" is coming from, seems to be part of the initial scaffolding. Any help appreciated.
Also - if there is a more straightforward way to integrate pg with sveltekit then I'm happy to hear about it. Thanks

My bad - the hooks function wasn't returning the response.
Hooks.server.js should read:
import { connectToDB } from '$lib/db';
export const handle = async ({event, resolve}) => {
const dbconn = await connectToDB();
event.locals = { dbconn };
const response = await resolve(event);
dbconn.release();
return response
}

Related

error in depolying contract >> Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)

im trying the depoy my contract using npx hardhat run scripts/deploy.js --network goerli and i keep geeting the above error
//this is the error
omota#DESKTOP-3T9OR5N MINGW32 ~/web3-projects/tinder-blockchain/smart-contract (main)
$ npx hardhat run scripts/deploy.js --network goerli
Compiled 1 Solidity file successfully
error in depolying contract >> Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.2)
at Logger.makeError (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\logger\src.ts\index.ts:281:20)
at EthersProviderWrapper.<anonymous> (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\src.ts\json-rpc-provider.ts:483:23)
at step (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\lib\json-rpc-provider.js:48:23)
at Object.throw (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\lib\json-rpc-provider.js:29:53)
at rejected (C:\Users\omota\web3-projects\tinder-blockchain\smart-contract\node_modules\#ethersproject\providers\lib\json-rpc-provider.js:21:65)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
reason: 'could not detect network',
code: 'NETWORK_ERROR',
event: 'noNetwork'
}
//here is my depoy.js file
const { ethers } = require('hardhat')
const main = async () => {
const tinderFactory = await ethers.getContractFactory('TinderERC721')
const tinderContract = await tinderFactory.deploy()
console.log('TINDER CONTRACT ADDRESS:', tinderContract.address)
};
main()
.then(() => process.exit(0))
.catch(error => {
console.log('error in depolying contract >>', error);
process.exit(1);
})
//here is my hardhat-config.js
require("#nomicfoundation/hardhat-toolbox");
require('dotenv').config({path: '.env'})
const ALCHEMY_API_URL = process.env.ALCHEMY_API_URL
const GOERLI_PRIVATE_KEY = process.env.GOERLI_PRIVATE_KEY
/** #type import('hardhat/config').HardhatUserConfig */
module.exports = {
defaultNetwork: 'goerli',
networks: {
goerli: {
url: ALCHEMY_API_URL,
accounts: [`0x${GOERLI_PRIVATE_KEY}`],
},
},
solidity: '0.8.17',
}
any help will be appreciated
i have done anything i can but still the same
I had the same error. Since you are using .env to store the private keys, if the value is being stored as:
"https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}" within the .env file itself, change it to the full link instead:
"https://eth-goerli.alchemyapi.io/v2/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
I was also getting a "private key too long" error as well because of using semi-colons to separate statements within the .env file... Hope this helps!
Maybe you have some problems with the ALCHEMY_API_URL. It should be in the form:
https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}
Or for sure, you can use public RPC nodes:
https://goerli.infura.io/v3/ //default on metamask
https://rpc.ankr.com/eth_goerli //I tried and it worked
https://eth-goerli.public.blastapi.io
https://rpc.goerli.mudit.blog

Next.js middleware to connect mongoose

I am working on a Next.js project and I want to connect it with MongoDB using mongoose. I want to make a middleware to run the connect function inside so I don't have to call connect function in each file I am using a mongoose model in.
this is my connect file:
// src/utils/connect.js
import mongoose from 'mongoose'
// getting the connection uri
const MONGO_URI = process.env.MONGO_URI
// checking if MONGO_URI is defined
if (!MONGO_URI) {
throw new Error(
'Please define the MONGO_URI environment variable inside .env.local'
)
}
// maintaining a cached connection to prevent reconnection (connections growing exponentially during API Route usage)
let cached = global.mongoose
// restiing the connection if there was no cached connection
if (!cached) {
cached = global.mongoose = null
}
/**
* mongodb connection
*/
export default async function connect() {
// returning the cached connection if it exists
if (cached) {
return cached
}
cached = await mongoose.connect(MONGO_URI, {
bufferCommands: false,
useNewUrlParser: true,
useUnifiedTopology: true
})
return cached
}
it will connect mongoose with my MongoDB database and caches the connection for future use.
this is one of my example API routes:
// src/pages/api/test.js
import connect from '../../utils/connect'
import Test from '../../models/Test';
export default async function handler(req, res) {
// connect
await connect()
const data = await Test.find({});
res.status(200).json({ name: 'John Doe', data })
}
now what I want to do is to get rid of that await connect() function in all routes and instead make a middleware to run the connect. and also is it better do so or not?

How to solve Vercel 500 Internal Server Error?

I have created a project that uses MongoDB to store user info and Next-Auth to authenticate users. On local host this is all working seamlessly. Previously I had a couple errors with my next-auth config, but that seems to be working fine now on Vercel live site. Once the user logs in they are redirected to "my-project/suggestions". On this page I am using getServerSideProps to identify if there is a valid session token. If so, data is pulled from a local json file.
On the live site, when the user logs in, the page is redirected to "/suggestions", yet I am receiving an 500 Internal Server Error page. On the function logs I am getting this error message:
[GET] /_next/data/KpsnuV9k44lUAhQ-0rK-B/suggestions.json
10:10:57:12
2022-05-05T14:10:59.270Z 5b7a7375-045f-4518-864b-7968c3c9385f ERROR [Error: ENOENT: no such file or directory, open '/var/task/public/data/data.json'] {
errno: -2,
syscall: 'open',
path: '/var/task/public/data/data.json',
page: '/suggestions'
}
RequestId: 5b7a7375-045f-4518-864b-7968c3c9385f Error: Runtime exited with error: exit status 1
Runtime.ExitError
This is my first project using MongoDB and Next-Auth.. not so sure what the issue is in this case. In my .env.local file I only have these two variables:
NEXTAUTH_SECRET="MUNKNATION"
NEXTAUTH_URL=http://localhost:3000
How I am pulling the data on local host:
export const getServerSideProps = async (context) => {
const session = await getSession({ req: context.req });
if (!session) {
return {
redirect: {
destination: "/",
permanent: false,
},
};
} else {
let filePath = path.join(process.cwd(), "public", "data", "data.json");
let jsonData = await fs.readFile(filePath);
const data = JSON.parse(jsonData);
const inProgressStatusData = data.productRequests.filter(
(item) => item.status == "in-progress"
);
const liveStatusData = data.productRequests.filter(
(item) => item.status == "live"
);
const plannedStatusData = data.productRequests.filter(
(item) => item.status == "planned"
);
let filterData = filteredData(data, "suggestion");
let feedbackData = {
suggestions: filterData,
progress: inProgressStatusData,
planned: plannedStatusData,
live: liveStatusData,
};
return {
props: { session, feedbackData },
};
}
};
Folder structure:
A simple solution to this problem would be to, inside of your getServerSideProps, instead of calling readFile use readFileSync as follows:
export const getServerSideProps = async (context) => {
...
const file = readFileSync(
join(process.cwd(), "public", "data", "data.json"),
"utf8"
);
const data = JSON.parse(fileData);
...
I have tested this solution with Vercel and it works correctly, in development and production mode.

Exceeded timeout of 5000 ms for a test with Jest and MongoDB

I'm trying to implement database population by using a migration function. The code works perfectly, it saves all the data into the database, but the test for the function is failing, and now I would like to know why?
I'm getting the "Exceeded timeout of 5000 ms" error for this particular test. I've written 166 tests for this app and all of them are passing.
Here is the function I want to test:
const doMigration = async ({ model, data }) => {
await model.collection.insertMany(data)
}
And here is the test:
const { Amodel } = require('../../../models/Amodel')
const { doMigration } = require('../../../database/migrations')
describe('Database Population', () => {
it ('Should populate the database using migrations', async () => {
const data = [{ name: 'A' }, { name: 'B' }]
const model = Amodel
const migration = { name: 'Amodel', model, data }
await doMigration(migration)
const countAfter = await Amodel.count()
expect(countAfter).toBe(2)
})
})
In this test I simply import the function, the model and create a migration object that then is passed to the function.
What did I try?
Tried using just the countAfter without using the doMigration function, and it still generates the same timeout error.
Tried increasing the time for this test to 30000, failed with error saying that the mongodb time exceeded the 10000 ms.
Here is the github repository: https://github.com/Elvissamir/Fullrvmovies
What is happening, how can I solve this error?
The problem was the way the mongodb connection was handled. When testing, the app created a connection to the db on startup, and then the jest tests used that connection, that caused some issues.
The solution was to connect to the database on startup only if the environment is set to testing, otherwise the connection will be handled by each set of tests.
In each set I added a beforeAll and afterAll to open and close the connection to the database.
Hope it helps anyone that finds the same problem or has similar issues.
The orientation is that the message reflect the actual reason, So i recommand to follow the following steps:
use the following code to check mongo state:
const { MongoMemoryServer } = require("mongodb-memory-server");
const mongoose = require("mongoose");
(async () => {
mongod = await MongoMemoryServer.create();
const mongoUri = mongod.getUri();
await mongoose.connect(mongoUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then((result) => {
console.log(result.connection.readyState)
console.log(result.connection.host)
}).catch((err) => {
});;
})();
if you are using mongodb-memory-server add "testTimeout" attribute:
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"setupFilesAfterEnv": [
"./src/test/setup.ts"
],
"testTimeout": 15000
},
If all above still huppens check the time-out of all inter-test operation

How to initialize Mongodb in NextJS startup

As you know NextJS is Jamstack framework and I'm migrating from node/express to it but my problem is how to connect server to database at startup of server as i did in express?
there is now where to put my initalizing code in NextJS? Am I saying correct?
I saw some code to to that but there were typescript codes that im not familiar with them
On the other hand i'm able to do that on serverside functions like getStaticProps or getServerSideProps this is my code
dbinit.js
import mongoose from "mongoose";
export const dbStatus = () => mongoose.connection.readyState;
export default function dbConnect() {
if (dbStatus == 1) return "database is connected";
mongoose.connect(
`mongodb://localhost:${process.env.DBPORT}/${process.env.DBNAME}`
);
}
index.js
export async function getServerSideProps() {
const result = await dbConnect();
console.log(dbStatus());
return {
props: {},
};
}
with this code im able to connect to mongodb but there are some problems and the most important is that mycode isnot cleancode
In NextJS, we can connect MongoDB as middleware. This is very similar to the Express middleware approach as shown below.
// middleware/database.js
import { MongoClient } from 'mongodb';
import nextConnect from 'next-connect';
const client = new MongoClient('{YOUR-MONGODB-CONNECTION-STRING}', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function database(req, res, next) {
if (!client.isConnected()) await client.connect();
req.dbClient = client;
req.db = client.db('MCT');
return next();
}
const middleware = nextConnect();
middleware.use(database);
export default middleware;
For more details, you can refer to this official how-to doc for step-by-step guidance. Here is the example repository used.