Broken pipe from ('127.0.0.1', <port no.>) 에러 해결기

느려도 꾸준한 발걸음·2024년 7월 22일
0

에러 해결기

목록 보기
5/7

(참고) 프론트엔드는 React, 백엔드는 DRF로 개발하고 있습니다.
참고 부탁드립니다.

1. 상황 설명

텍스트만 업로드 가능하던 기존 게시판에,
이미지도 업로드가 가능하도록 기능을 추가하다 마주친 에러입니다.

form 에 제목과 내용을 입력하고, 원하는 이미지를 선택한 뒤
업로드하기 버튼을 누르는 순간,
다음과 같은 에러가 발생하였습니다.

Broken pipe 에러가 발생했습니다.

2. Broken Pipe 에러란?

Broken pipe 에러는 무엇이고, 언제 발생할까요?

Broken pipe 에러는 클라이언트와 서버의 통신이 비정상적으로 끊어질 때 발생합니다.

해야 하는 작업이 남아있는데, 완료 되기도 전에 모종의 이유로 연결이 끊어져버린 것이죠.

서버와 클라이언트의 비정상적인 통신중단 에러이니,
프론트엔드와 백엔드 둘 모두가 에러의 원인이 될 수 있기에,
프론트와 백 측의 코드를 모두 확인하며 잘못된 부분을 찾아야 합니다.

먼저 프론트엔드측 코드의 경우, 아래의 사항들을 점검해보아야 합니다.

  • 서버로 보내는 데이터의 형식(헤더의 Content-Type)이 유효한가? - axios 설정 확인
  • 요청 엔드포인트가 정확한가?
  • 데이터가 중간에 유실되지 않고 서버까지 무사히 도달할 수 있는가?

백엔드 측 코드의 경우, 아래의 사항들을 점검해보아야 합니다.

  • CORS 관련 설정이 잘 되어있는가?
  • View 및 url 설정이 잘 되어있는가?

3. 원인 및 해결

저의 경우, 클라이언트 측의 코드에 문제가 있었습니다.
지금 생각해보면 정말이지 너무나 허무합니다.

아래는 문제가 되었던 코드 스니펫입니다.

const handleSubmit = async (e) => {

    let multiTypeformData = new FormData();

    multiTypeformData.append("title", formData.title);
    multiTypeformData.append("content", formData.content);
    multiTypeformData.append("author", author.id);
    multiTypeformData.append("email", author.email);

    //이미지가 있는 경우에만 업로드
    if (image) {
      multiTypeformData.append("image", image);
    }

    try {
      await axiosInstance.post("create/", multiTypeformData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      });
      navigate("/home"); // 피드 화면으로 리다이렉팅
    } catch (error) {
      console.error("There was an error uploading the post!", error);
    }
  };

⬇️ axiosInstance 코드 참고

import axios from "axios";

const baseURL = "http://127.0.0.1:8000/api/";

const axiosInstance = axios.create({
  baseURL: baseURL,
  timeout: 5000,
  headers: {
    //django 설정 파일에서 simple jwt header type에 JWT주었음
    Authorization: localStorage.getItem("access_token")
      ? "JWT " + localStorage.getItem("access_token")
      : null,
    "Content-Type": "application/json",
    accept: "application/json",
    // responseType: "json",
  },
});

앞서, 프론트엔드측 코드의 경우, 아래의 사항들을 점검해보아야 한다고 했습니다.

    1. 서버로 보내는 데이터의 형식(헤더의 Content-Type)이 유효한가? - axios 설정 확인
    1. 요청 엔드포인트가 정확한가?
    1. 데이터가 중간에 유실되지 않고 서버까지 무사히 도달할 수 있는가?

제 코드의 경우 1번과 2번은 모두 문제가 없었습니다.

백엔드의 엔드포인트도 정확히 입력하였고,
기존 json형식이던 axiosInstance의 Content-Type도
이미지를 추가하며 "multipart/form-data" 로 덮어씌워 수정하였습니다.

제 코드의 경우, 3번 조건을 만족시키지 못하였습니다.

제 코드는, multiTypeformData를 서버로 보내지 못하고 있었습니다.
이유는, submit이벤트 핸들러에 브라우저의 디폴트 동작을 방지하는 코드 한 줄이 누락되었기 때문입니다.

e.preventDefault();

머리가 띵했습니다.

며칠을 고생했는데, 생각하지도 못한 이런 허무한 실수가 원인이었다니,
허탈한 웃음만 나왔습니다.

그래도, 이참에 위의 코드 한 줄이 어떤 기능을 하는지 제대로 정리해보겠습니다.

e.preventDefault(); 는, form 을 제출했을 때 브라우저가 기본적으로 수행하는 동작을 차단해줍니다.

브라우저는 기본적으로 폼이 제출되면 페이지를 새로고침합니다.

문제는,
페이지가 새로고침되면 클라이언트와 서버의 연결이 끊어지고,
서버로 전송되어야 할 데이터가 중간에 유실될 수 있다는 것입니다.

이를 방지하고자 모든 submit이벤트 핸들러에선 e.preventDefault(); 를 먼저 작성하고 내부 로직을 구현하는 것이 관례입니다.

4. 마무리 및 교훈

오늘은 broken pipe에러에 대해 알아보았습니다.
해당 에러는 서버와 클라이언트의 연결이 비정상적으로 중단되어 발생하는 에러였습니다.

해당 에러가 발생하면, 아래의 사항들을 점검해보야 합니다.

프론트엔드

  • 서버로 보내는 데이터의 형식(헤더의 Content-Type)이 유효한가? - axios 설정 확인
  • 요청 엔드포인트가 정확한가?
  • 데이터가 중간에 유실되지 않고 서버까지 무사히 도달할 수 있는가?

백엔드

  • CORS 관련 설정이 잘 되어있는가?
  • View 및 url 설정이 잘 되어있는가?

또한, 아주 기본적인 사항이지만,
폼 제출 이벤트 핸들러에선 반드시 브라우저의 디폴트 동작을 방지시켜주어야 합니다.

감사합니다.

profile
웹 풀스택 개발자를 준비하고 있습니다. MERN스택을 수상하리만큼 사랑합니다.

0개의 댓글