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

ECONNRESET error on React #845

Open
2 tasks done
KozyWorks opened this issue Oct 27, 2022 · 2 comments
Open
2 tasks done

ECONNRESET error on React #845

KozyWorks opened this issue Oct 27, 2022 · 2 comments

Comments

@KozyWorks
Copy link

KozyWorks commented Oct 27, 2022

Checks

Describe the bug (be clear and concise)

As a part of my React (front) / Express (backend) project, I have a web crawler that crawls buffer, decodes then obtain desired data using cheerio.

(Just to clarify, I am not using any data obtained for commercial use, but only for a personal project.)

server.js:

require("dotenv").config();

const express = require("express");
const cors = require("cors");
const http = require("http");
const axios = require("axios");
const cheerio = require("cheerio");

const app = express();
app.set("port", process.env.PORT || 3001);
app.use(cors());
app.use(
    express.json({
        verify: (request, _, buffer) => {
            request.buffer = buffer;
        },
    })
);

app.get("/", (_, response) => {
    response.send("index");
});

app.get("/:menu_id", async (request, response) => {
    try {
        const buffer = await axios.get("https://cafe.naver.com/ArticleList.nhn", {
            params: {
                "search.clubid": 10050146,
                "search.menuid": request.params.menu_id,
                "search.boardType": "L",
                userDisplay: 10,
            },
            headers: {
                "Content-Type": "application/json",
            },
            responseType: "arraybuffer",
        });

        const decoder = new TextDecoder("EUC-KR");
        const content = decoder.decode(buffer.data);
        const $ = cheerio.load(content);
        const list = $("div.article-board:nth-of-type(4)>table>tbody>tr");

        let articles = [];

        list.each((_, tag) => {
            const url = `https://cafe.naver.com${$(tag).find("a.article").attr("href")}`;
            const number = $(tag).find("div.inner_number").text();
            const title = $(tag).find("a.article").contents().last().text().trim();
            const author = $(tag).find(".p-nick>a").text();
            const date = $(tag)
                .find("td.td_date")
                .text()
                .replace(/(\d{4}).(\d{2}).(\d{2})./g, "$2-$3");
            articles.push({ number, title, author, date, url });
        });

        response.send(articles);
    } catch (error) {
        response.send(error);
    }
});

const server = http.createServer(app);
server.listen(app.get("port"), () => {
    console.log(`App is listening to port: ${app.get("port")}`);
});

Then I have setup a proxy using http-proxy-middleware on front-end.

setupProxy.js:

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = (app) => {
    app.use(
        createProxyMiddleware("/api", {
            target: "http://localhost:3001",
            changeOrigin: true,
            pathRewrite: {
                "^/api": "",
            },
        })
    );
};

Articles.js:

import React, { useEffect, useState } from "react";
import axios from "axios";

import Article from "./Article";
import Loading from "./Loading";

const Articles = (props) => {
    const [articles, setArticles] = useState();

    useEffect(() => {
        const getArticles = () => {
            axios
                .get(`/api/naver/cafe/${props.menu.id}`)
                .then((response) => {
                    console.log(response);

                    setArticles(response.data);
                })
                .catch((error) => {
                    console.log(error);
                });
        };

        getArticles();
    }, []);

    return (
        <div className="articles">
            <div className="menuTitle">{props.menu.title}</div>
            {articles ? (
                <ul className="menuContent">
                    {Object.entries(articles).map(([key, article]) => (
                        <Article article={article} key={key} />
                    ))}
                </ul>
            ) : (
                <Loading />
            )}
        </div>
    );
};

export default Articles;

So, this actually works and fetches data as I expected, but then when the server is left running idle, doing nothing, the client fails to fetch data from the server on page refresh (or maybe on a new session) and spits the long, long error below:

/project/node_modules/axios/dist/node/axios.cjs:725
  AxiosError.call(axiosError, error.message, code, config, request, response);
             ^
AxiosError: read ECONNRESET
    at AxiosError.from (/project/node_modules/axios/dist/node/axios.cjs:725:14)
    at RedirectableRequest.handleRequestError (/project/node_modules/axios/dist/node/axios.cjs:2467:25)
    at RedirectableRequest.emit (node:events:513:28)
    at eventHandlers.<computed> (/project/node_modules/follow-redirects/index.js:14:24)
    at ClientRequest.emit (node:events:513:28)
    at TLSSocket.socketErrorListener (node:_http_client:494:9)
    at TLSSocket.emit (node:events:513:28)
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
    ...

It just feels like the client loses the connection to the server via proxy.

Here's the things I've tried:

  1. adding connection: "keep-alive" option to createProxyMiddleware header
  2. switching http request client to built in fetch from axios
  3. trying full length(?) url instead of shortified version (/api/naver/cafe/${props.menu.id}http://localhost:3000/api/naver/cafe/${props.menu.id})

and nothing really resolved the issue.

The only way to fix this error is either by refreshing the page until it works or restarting the server.

I do have some Twitch's helix related apis as well, but this error only occurs with the crawling function above.

Literally spent hours and hours to troubleshoot this... and failed.

Any ideas, please?

I am using NodeJS v18.10.0 btw.

Step-by-step reproduction instructions

Please find the code attached on the main text

Expected behavior (be clear and concise)

Fetch data from server with no issue

How is http-proxy-middleware used in your project?

> yarn why http-proxy-middleware
yarn why v1.22.19
[1/4] Why do we have the module "http-proxy-middleware"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "http-proxy-middleware@2.0.6"
info Has been hoisted to "http-proxy-middleware"
info Reasons this module exists
   - Specified in "dependencies"
   - Hoisted from "react-scripts#webpack-dev-server#http-proxy-middleware"
info Disk size without dependencies: "156KB"
info Disk size with unique dependencies: "568KB"
info Disk size with transitive dependencies: "4.62MB"
info Number of shared dependencies: 10
Done in 0.41s.

What http-proxy-middleware configuration are you using?

const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = (app) => {
    app.use(
        createProxyMiddleware("/api", {
            target: "http://localhost:3001",
            changeOrigin: true,
            pathRewrite: {
                "^/api": "",
            },
        })
    );
};

What OS/version and node/version are you seeing the problem?

- Ubuntu 22.04
- Node JS 18.10.0
- react-script 5.x

Additional context (optional)

No response

@nfdenuzzo
Copy link

Any 1 ever figure this out?

@elawad
Copy link

elawad commented Apr 28, 2024

This worked for us using CRA@5 and HPM@3.

const proxy = createProxyMiddleware({
  target: 'http://localhost:3001',
  changeOrigin: true,
  pathFilter: '/api',
});

module.exports = (app) => app.use(proxy);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants