Suddenly started encountering Internal Server Error 500 on Mac for React App with Express server - node.js

In my react app I have an API that I am calling from my redux-saga. I am using express for my server. The code has been hosted and is working just fine. But today, I deleted the build directory and reran npm run build and then npm start and started getting this error on my local Mac.
Error on Chrome:
The error in index.js expanded if it helps:
Error on Safari:
I am pretty sure my code is proper as it has been running just fine for months now and I have made no major changes right now expect adding some console.log statements.
My API in Express Server:
app.get("/api/getProblems", (req, res) => {
var sheetKey = SECRET_KEY;
tabletop.init({
key: sheetKey,
callback: (sheet) => {
res.json(sheet);
console.log("Sent list of problems");
},
simpleSheet: true,
});
});
Calling from Saga:
function* fetchProblems() {
const data = yield call(() =>
fetch("/api/getProblems")
.then(response => response.json())
.then(sheet => sheet)
);
//Rest of the logic
}
For a brief moment I was seeing the following error:
Could not proxy request /api/getProblems from localhost:3000 to http://localhost:8000 (ECONNREFUSED)
But then it was replaced by the above error.

It was my mistake in starting the server. I ran npm start in the wrong folder. From the root I had to run the following commands:
cd client; npm run build; cd ..; npm start;

Related

How to run electron on a localhost server in Build as well as in Dev

I'm developing with Next.js + Electron + Typescript.
I'm using the npx create-next-app --example with-electron-typescript command to generate code.
npm run dev (the contents are npm run build-electron && electron . ), it seems that the local server is up and running on localhost8000, but when build, the server is not up internally, and it is running by directly accessing the file.
However, some APIs do not work correctly if there is no domain in the location.origin , so it works in Dev, but does not work in Build.
So, if it is possible, I would like to run the server on localhost in the build version as well as in the Dev version.
Is there anything I can do to make it work?
It's not shown in any of the examples, even though someone requested one:
https://github.com/vercel/next.js/issues/28225
It is possible using a custom server:
https://nextjs.org/docs/advanced-features/custom-server
You can follow these steps to create one:
Clone the Electron Next TypeScript example repo:
https://github.com/vercel/next.js/tree/canary/examples/with-electron-typescript
Update ./electron-src/index.ts with the following code:
import isDev from 'electron-is-dev';
import { createServer } from 'http';
import next from 'next';
import { parse } from 'url';
app.on('ready', async () => {
// Use server-side rendering for both dev and production builds
const nextApp = next({
dev: isDev,
dir: app.getAppPath() + '/renderer'
});
const requestHandler = nextApp.getRequestHandler();
// Build the renderer code and watch the files
await nextApp.prepare();
// Create a new native HTTP server (which supports hot code reloading)
createServer((req: any, res: any) => {
const parsedUrl = parse(req.url, true)
requestHandler(req, res, parsedUrl)
}).listen(3000, () => {
console.log('> Ready on http://localhost:3000')
})
mainWindow.loadURL('http://localhost:3000/')
Update ./package.json Electron build configuration to include the renderer src files:
"build": {
"asar": true,
"files": [
"main",
"renderer"
]
}
In ./package.json move next from devDependencies to dependencies. This means it will be available to run in production builds
Then use helpful scripts to unpack the binary and see the files/folder inside:
npx asar extract ./dist/mac/ElectronTypescriptNext.app/Contents/Resources/app.asar ./dist/unpack
Run the unpacked version to debug:
./node_modules/.bin/electron ./dist/unpack
I have created an Express Server version and NextJS versions to prove it is possible:
https://github.com/kmturley/electron-server/tree/feature/express
https://github.com/kmturley/electron-server/tree/feature/next

My CRUD app works locally but not on Heroku

I've created a CRUD app and it works locally, but I can't get it to work fine on heroku. It deploys correctly, the website seems to work, but then I can't get the items I need from the database, as it keeps saying connection refused.
I added the .env variables to Heroku, as well as setting the port to process.env.PORT || 5000 and app.listen(port), I'm not sure what's causing the error. I also have a Procfile with web: node server.js, and a "start" script in package.json that points to server.js. It seems that the server doesn't start at all.
Here the repo in case you want to have a look https://github.com/ThomYorke7/inventory, here the app on heroku https://boardgamenerd.herokuapp.com/
The problem lies in the fact that your application has a backend (server) and a frontend (client) which are served differently locally than on Heroku.
I suppose locally your client is running on localhost:3000 (as it is the default with create-react-app you bootstrapped).
While your backend is running on localhost:5000, your client's package.json contains this line to make it work locally:
"proxy": "http://localhost:5000",
If I visit this page of your app: https://boardgamenerd.herokuapp.com/ > boardgames,
then I face these errors on the browser console:
boardgames-list.jsx:18
Error: Network Error
at e.exports (createError.js:16)
at XMLHttpRequest.p.onerror (xhr.js:83)
xhr.js:178
GET http://localhost:5000/boardgames/ net::ERR_CONNECTION_REFUSED
It tells you that your production version still calls backend on localhost:5000.
I.) First I'd try to fix these fetches by changing to relative URLs.
E.g. the above example (boardgames-list.jsx:18)
❌ your current script has hardcoded localhost fetch at the moment:
useEffect(() => {
axios
.get('http://localhost:5000/boardgames/')
.then((response) => {
setBoardgames(response.data);
setLoading(false);
})
.catch((err) => console.log(err));
}, []);
✔️ make it relative to root by removing "http://localhost:5000":
useEffect(() => {
axios
.get('/boardgames/')
.then((response) => {
setBoardgames(response.data);
setLoading(false);
})
.catch((err) => console.log(err));
}, []);
And it will work on Heroku. In case it wouldn't: see my suggestion below.
II.) Second, a suggestion:
Now your https://boardgamenerd.herokuapp.com/boardgames route uses the following backend endpoint to fetch data: https://boardgamenerd.herokuapp.com/boardgames/
The difference is only the last slash ("/") character which can be confusing and cause more issues later!
It is a best practice to add a differentiator path element to your backend endpoints, like /api/. For example: https://boardgamenerd.herokuapp.com/api/boardgames So you can be sure by first sight which GET request related to the backend and which one to the client.
If you'd go with this solution, you will need to add the following to your server.js:
app.use(express.static(path.join(__dirname, 'client', 'build')))
// required to serve SPA on heroku production without routing problems; it will skip only 'api' calls
if (process.env.NODE_ENV === 'production') {
app.get(/^((?!(api)).)*$/, (req, res) => {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'))
})
}
/^((?!(api)).)*$/ regex skips URLs containing "api" in their path, so they won't be served static as the client/build folder's content - api calls won't be served from static and will work fine.

NPM and NodeJS Compatibility: NodeJS works from PM prompt, but not script

I am attempting to get a lighthouse script running in Node.JS (which I am new to). I followed the intial instructions here https://github.com/GoogleChrome/lighthouse/blob/master/docs/readme.md#using-programmatically. I was able to complete the prior steps in the package manager console (Visual Studio 2017):
npm install -g lighthouse
lighthouse https://airhorner.com/
//and
lighthouse https://airhorner.com/ --output=json --output-path=./report/test1.json
However, I do get an initial warning that NPM only supports Node.JS in versions 4 through 8 and recommends a newer version. The problem is I am running Node v12 and NPM v5 - both the latest.
When I create a script version like below (app.js)
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
const config = {
extends: 'lighthouse:default',
settings: {
emulatedFormFactor: 'desktop',
onlyCategories: 'performance',
output: 'json',
outputPath: './report.json'
}
};
function launchChromeAndRunLighthouse(url, opts = null, config) {
return chromeLauncher.launch().then(chrome => {
opts.port = chrome.port;
return lighthouse(url, opts, config).then(results => {
return chrome.kill().then(() => results.lhr);
});
});
}
// Usage:
launchChromeAndRunLighthouse('https://airhorner.com/', config).then(results => {
// Use results!
});
And run the command
C:\src\project> node app.js
I get the error - Cannot find module 'lighthouse'
don't install lighthouse locally use it inside your working dir .
first start by running npm init that will create the package.json file inside the current working dir
then npm install --save lighthouse will download it and save it to node_modules now you can use it locally inside your working dir
it should look something like this
app.js
package.json
node_modules/
then run node app.js

React Native unable to run a successful fetch to express API

Given the following setup:
server.js
const express = require('express')
const path = require('path')
const app = express()
const cors = require('cors')
const port = process.env.PORT || 8080
app.use(cors())
app.get('/api', (req, res) => {
res.send({code: 200, message: 'I have arrived!'})
})
app.listen(port, () => console.log(`I can hear your thoughts on ${port}`))
and the presentational component with call:
App.js
componentDidMount() {
fetch(`/api`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(res => {
console.log(res)
return res.json()
}).then(response => {
console.log(response)
this.data = response
}).catch(error => {
this.error = error.message || error.error
})
}
package.json:
"scripts": {
"start": "npm-run-all --parallel start:client start:server",
"start:client": "node node_modules/react-native/local-cli/cli.js start",
"start:server": "node server.js",
"test": "jest"
},
I am running the app via yarn start, and I see the log: "I can hear your thoughts"... The fetch call, however, is never made. If I supply another fully qualified url within the fetch call it returns the data as expected, however I am unable to hit the express api from within the component.
If I place http://localhost:8080/api in the browser I get the response.
If I place http://localhost:8080/api in the fetch call it is never called (or at least doesn't appear to be).
How can I properly configure this to call the express api when running locally?
As always any and all direction is appreciated, so thanks in advance!
I believe the issue for this is two fold.
Firstly you are running the server and the bundler in the same terminal window. I believe that this is causing them to get confused.
Run them in separate windows. Yes that means you have to run an extra command but it will mean that you will be able to clearly see the logs for each of them.
Also you may have to restart you bundler, especially when you add new packages which will mean restarting your server.
Similarly when you update your server you will have to restart it also causing you to restart your bundler. It doesn't seem like a good idea running them in the same window.
Secondly you are using the localhost for the api. This works nicely on your computer because the api is running on your computer's localhost so it can find it. However, when you run it on a device and you use localhost it looks for the api on your device's localhost and cannot find it there, thus it doesn't bring back a result.
Your solution is quite clear. Firstly, run your bundler and your server in different terminal windows. And secondly use the ip address of your computer so that the emulator/simulator can easily find where the api is located.
I copied your code and made only two changes to the react-native code.
Added alerts to show the response and error from the fetch request
Used my local ip address of my computer rather than localhost
Here are some images of me running it on both Android and iOS, using your code and the changes that I detailed above.
Android
iOS

Ionic 2 Http.post hangs nodeJS express server

I have a CouchDB database, and a nodeJS with express to make an API using couchdb-promises library.
In ionic 2 provider I do:
login(credentials) {
let params = {
username: credentials.email.toLowerCase(),
password: SHA3(credentials.password).toString()
};
return new Promise((resolve, reject) => {
this.http.post(API + '/auth/login', params)
.map(res => res.json())
.subscribe(data => {
localStorage.setItem('user', JSON.stringify(data.user));
resolve(true);
});
},
error => {
reject(Error(error._body));
});
});
}
It works fine the first time, but if I logout and try again, request hangs server and does not work. I need to restart server app in order to login again.
If I request via curl, I can post as many times as I want, but if I first login in Ionic 2 app, and then I send a curl request, I have not response either.
I first thougth it is problem in server side (and I tried other versions of nodejs), but only happens if I do the Ionic Http.post. Other request also hangs server, not only login. Seems only can be done one request at all.
What could be happening? Should I finalize the requests in any way?
Cordova CLI: 6.3.1
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
OS: Linux 4.4
Node Version: v7.8.0
express: 4.15.2
couchdb-promises: 3.0.0
The problem is not Ionic 2 itself, using in server nano instead of couchdb-promises works fine.
Still having no idea why couchdb-promises hangs with Ionic and does not with normal request.

Resources