i have static app with nextJs 13 without any api data or database in my local machine it work normal ,but in production server with cpanel i have 503 error with this log
node:events:491
throw er; // Unhandled 'error' event
^
Error: read EINVAL
at Pipe.onStreamRead (node:internal/stream_base_commons:217:20)
Emitted 'error' event on Socket instance at:
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
errno: -22,
code: 'EINVAL',
syscall: 'read'
}
I followed the documentation steps and i change scripts start and i add my custom server also
package.json
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') {
await app.render(req, res, '/a', query)
} else if (pathname === '/b') {
await app.render(req, res, '/b', query)
} else {
await handle(req, res, parsedUrl)
}
} catch (err) {
console.error('Error occurred handling', req.url, err)
res.statusCode = 500
res.end('internal server error')
}
}).listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://${hostname}:${port}`)
})
})
Related
For some time now, we no longer see any stack traces server-side in dev. Attempts to remedy this situation have included:
const server = express();
server.use((err, req, res, next) => {
console.error('err', err);
next(err);
// res.status(500).send('Something broke!');
});
and
const errorHandler = require('errorhandler');
server.use(
errorHandler({
log(err, str, req) {
console.log('log error', err);
console.log('str', str);
// console.log('req', req);
},
})
);
all to no avail.
For example:
server.get('/crash', (req, res, next) => {
boom; // this line crashes
});
calling this endpoint does indeed crash, but no stack trace is visible in the server log.
We launch with:
npm run debug
which is configured like this in package.json:
"scripts": {
"debug": "node --max-old-space-size=4096 --inspect node_modules/nuxt/bin/nuxt",
What are we doing wrong?
so, after trying a few times, it is clear that I am doing something wrong but I do not realize what. My steps are:
rm -rf .next/ && npm run build
upload .next, package.json,next.config.js and server.js to cPanel file manager
create node JS app from cPanel with 14.18.3 version. (on my local node -v show me 14.18.1, but on cPanel I don't have this version)
run npm install with success
then i'm geting 503 service unavailable.
server.js
// server.js
const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const hostname = 'localhost';
const port = process.env.PORT || 3000;
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
if (pathname === '/a') {
await app.render(req, res, '/a', query);
} else if (pathname === '/b') {
await app.render(req, res, '/b', query);
} else {
await handle(req, res, parsedUrl);
}
} catch (err) {
console.error('Error occurred handling', req.url, err);
res.statusCode = 500;
res.end('internal server error');
}
}).listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://${hostname}:${port}`);
});
});
package.json scripts
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
next.config.json
/** #type {import('next').NextConfig} */
const nextConfig = {
basePath: '/apps/nextjs-cpanel',
trailingSlash: true,
reactStrictMode: true,
sassOptions: {
additionalData: `#import "./styles/variables.scss"; #import "./styles/mixins.scss";`,
}
};
module.exports = nextConfig;
on cPanel application root is apps/nextjs-cpanel, application url is my-domain/apps/nextjs-cpanel and application startup file server.js
I'm workin with a custom error response that I found in a tutorial. it's working correctly in all the node server, but in a specifies line it doesn't take the argument that specified the error code. It should return a 401 error but instead is returning me a 500 error code.
errorResponse.js
class ErrorResponse extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
module.exports = ErrorResponse;
The next is the porcion of code that doesn't working well.
auth.js
return next(new ErrorResponse('Unauthorized', 401))
If I use this aproach the error code is the correct.
return res.status(401).json('Unauthorized')
Edited and share server.js
require('dotenv').config({path: './config.env'});
const express = require('express');
const connectDB = require('./config/db');
const errorHandler = require('./middlewares/error');
connectDB();
const app = express();
app.use(express.json());
app.use('/api/auth', require('./routes/auth'));
app.use('/api/private', require('./routes/private'));
const PORT = process.env.PORT || 5000;
const server = app.listen(PORT, () => console.log('server on port', PORT));
process.on("unhandledRejection", (err, promise) => {
console.log(`logged Error: ${err}`)
server.close(() => process.exit(1))
});
app.use(errorHandler);
error.js
const errorHandler = (err, req, res, next) =>{
let error = { ...err };
error.message = err.message
if(err.code === 11000) {
const message = `Error de duplicaciĆ³n`;
error = new ErrorResponse(message, 400)
}
if(err.name === "ValidationError") {
const message = Object.values(err.errors).map((val) => val.message);
err = new ErrorResponse(message, 400)
}
res.status(error.status || 500 ).json({
succes: false,
error: error.message || "Error del servidor"
})
}
Before uploading my code to Heroku, my API calls worked just fine. However, it returns a status code of 503 (Service Unavailable) after deployment.
This is my code
app.js file in my root folder (server file)
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true }).then(() => console.log("Connected to db!")).catch(dbErr => console.log(dbErr));
app.use(express.json());
app.use(cors());
app.post("/post-result", async (req, res) => {
console.log(req.body.val);
const newSurvey = new survey({ surveyValues: req.body.val });
await newSurvey.save()
.then(data => {
res.send(newSurvey);
console.log(newSurvey);
}).catch(err => console.log(err));
});
app.get("/results", async (req, res) => {
const result = await survey.find({});
res.send(result);
});
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "/client/build")));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
})
} else {
app.get("/", (req, res) => {
res.send("API running");
})
}
app.listen(process.env.PORT, () => console.log("Listening on PORT 8080"));
My react file, where the API calls were made
const handleFormSubmit = async (e, val) => {
const { data } = await Axios.post("/post-result", { val });
}
package.json file
{
"scripts": {
"start": "nodemon app.js",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"mongoose": "^6.0.12"
}
}
Error log in the console
Uncaught (in promise) Error: Request failed with status code 503 at e.exports createError.js:16) at e.exports (settle.js:17) at XMLHttpRequest.S (xhr.js:66)
Option 1 :
Maybe you should try using all the url instead of Axios.post("/post-result",{..}) You can use local variable to determine if you are in Prod or in local environment, create in util folder a file called for example baseUrl.js :
const baseUrl = process.env.NODE_ENV === "production"
? "https://[your url used in port]"
: "http://localhost:[your port]";
export default baseUrl;
And then import baseUrl in your folder and replace your Axios request by :
const { data } = await Axios.post(baseUrl + "/post-result", { val });
Option 2 :
Also I noticed that you don't allow any URL in Cors Options :
let corsOptions = {
origin: ["URL ALLOWED", ...],
};
app.use(cors(corsOptions));
I have the following test code:
const compression = require('compression');
const bodyParser = require('body-parser')
const cors = require('cors')
const { pool, connectionString } = require('./config')
const { handleError, ErrorHandler } = require('./error')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(cors())
app.use(compression());
const getEvents = (request, response) => {
pool.connect((err, client, release) => {
if (err) {
throw new ErrorHandler(500, err.stack);
}
if(!request.query.FromTime){
throw new ErrorHandler(400, 'Required paramter FromTime is missing.');
}
if(!request.query.ToTime){
throw new ErrorHandler(400, 'Required paramter ToTime is missing.');
}
let fromtime = request.query.FromTime
let totime = request.query.ToTime
console.log("FromTime: ",fromtime," ToTime: ",totime);
let query = 'SELECT data FROM logs WHERE time BETWEEN '+fromtime+' AND '+totime+' ORDER BY time DESC';
console.log(query)
var stream = client.query(query, (error, results) => {
if (error) {
throw new ErrorHandler(500,error);
}
response.status(200).json(results.rows)
})
})
}
...
app
.route('/events')
// GET endpoint
.get(getEvents)
// POST endpoint
.post(addEvent)
app.use((err, req, res, next) => {
handleError(err, res);
});
// Start server
app.listen(process.env.PORT || 3002, () => {
console.log(`Server listening`)
})
I have been trying to get this to stream data instead but unsuccessfully. I did try pg-query-stream, with querystream but ended up with the following error, when i tried
var stream = client.query(new QueryStream(query));
stream.pipe(response);
_http_outgoing.js:607
throw new ERR_INVALID_ARG_TYPE('first argument',
^
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of
type string or Buffer. Received type object
at write_ (_http_outgoing.js:607:11)
at ServerResponse.write (_http_outgoing.js:579:10)
at ServerResponse.write (/usr/src/app/node_modules/compression/index.js:89:18)
at PgQueryStream.ondata (_stream_readable.js:705:22)
at PgQueryStream.emit (events.js:193:13)
at addChunk (_stream_readable.js:295:12)
at readableAddChunk (_stream_readable.js:276:11)
at PgQueryStream.Readable.push (_stream_readable.js:231:10)
at cursor.read (/usr/src/app/node_modules/pg-query-stream/index.js:55:14)
at Immediate.setImmediate (/usr/src/app/node_modules/pg-cursor/index.js:91:7)
response stream is not supported object mode by default.
Just try like in documents
const JSONStream = require('JSONStream')
stream.pipe(JSONStream.stringify()).pipe(response)