타입스크립트로 작성된 (로깅이 절반인) 게시물 작성 코드!
// 게시물 작성
static createPost = [
(req: Request, res: Response, next: NextFunction) => {
console.log("Request received, multer about to process the file.");
console.log("Request headers:", req.headers); // 전체 헤더 로깅
console.log("Request body size:", req.headers['content-length']); // 요청 바디 크기 확인
next();
},
upload.single('media'), // 미들웨어로 multer 추가
async (req: Request, res: Response, next: NextFunction) => {
try {
console.log("Multer processed the file.");
console.log('Form data:', req.body);
if (req.file) {
console.log('Uploaded file:', req.file);
} else {
console.log('No file uploaded');
}
// 필드 유효성 검사
const { title, feedbackRequest, keyPoint, categoryId } = req.body;
const userId = (req.user as User)?.id;
if (!userId || !title || !feedbackRequest || !categoryId) {
console.error('필수 필드가 누락되었습니다.');
return res.status(400).json({ message: '필수 필드가 누락되었습니다.' });
}
// 저장소 가져오기
const postRepository = AppDataSource.getRepository(Post);
const menteeRepository = AppDataSource.getRepository(Mentee);
const categoryRepository = AppDataSource.getRepository(Category);
const userRepository = AppDataSource.getRepository(User);
// 사용자, 멘티, 카테고리 찾기
const user = await userRepository.findOne({ where: { id: userId } });
const mentee = await menteeRepository.findOne({ where: { user: { id: userId } } });
const category = await categoryRepository.findOne({ where: { id: categoryId } });
if (!user || !mentee || !category) {
console.error('사용자, 멘티 또는 카테고리를 찾을 수 없습니다.');
return res.status(404).json({ message: '사용자, 멘티 또는 카테고리를 찾을 수 없습니다.' });
}
// 게시물 생성
const newPost = postRepository.create({
title,
feedbackRequest,
keyPoint,
category,
user,
mentee,
status: 'pending',
mediaPath: req.file ? req.file.path : null, // 파일 경로 저장
});
await postRepository.save(newPost);
console.log("게시물 생성 완료:", newPost);
return res.status(201).json(newPost);
} catch (error: unknown) {
if (error instanceof multer.MulterError) {
console.error('Multer error:', error);
return res.status(400).json({ message: '파일 업로드 오류', error: error.message });
} else if (error instanceof Error) {
console.error('서버 오류:', error.message, error.stack); // 오류 메시지와 스택 트레이스 로깅
return res.status(500).json({ message: '서버 오류', error: error.message });
} else {
console.error('알 수 없는 오류:', error);
return res.status(500).json({ message: '알 수 없는 서버 오류' });
}
}
}
];
뭔가 파일 업로드 테스트 할 때 포스트맨은 이미 진행했지만, 불안한 마음에 간단한 테스트용 html 파일을 작성했었다.
(프론트 개발자로 입사 희망하던 상태였기에 대학 졸업까지 프론트 공부만 하고, 인턴도 프론트엔드 개발자만 했었는데 입사 후 백엔드 개발자가 됐습니다... 회사 홈페이지 리뉴얼은 관리자 페이지만 손 봤기 때문에 본격적으로 하는 건 이번이 처음이라 불안한 마음..... 가득)
fetch('/api/posts', {
method: 'POST',
body: formData,
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`
}
})
분명 API 요청할 때도 body: formData 로 잘 넣어뒀는데 왜 계속 이런
에러 발생: Error: Unexpected end of form
at Multipart._final (프로젝트위치/types/multipart.js:588:17)
at prefinish (node:internal/streams/writable:907:14)
at finishMaybe (node:internal/streams/writable:921:5)
at Multipart.Writable.end (node:internal/streams/writable:836:5)
at onend (node:internal/streams/readable:946:10)
at processTicksAndRejections (node:internal/process/task_queues:77:11)
POST /api/posts 500 111.959 ms - 16
오류가 나는가 했다... 이럴 때 구글링을 좀 더 열심히 해야되는데 애꿎은 코드 잘못인 줄 알고 별의 별 디버깅을 다 해봤다.
upload 미들웨어 코드도 수정하고 컨트롤러에서 게시물 작성 하나 할 때 로그를 엄청 넣었다 ㅋㅋㅋㅋㅋ ㅠㅠ
하지만 결국 해결하지 못했고... 구글링을 진행한 결과
깃헙 multer 레포 이슈 부분에 이런 친절한 설명이 .. ^^
tgroshon님의 말을 듣고 버전을 1.4.3으로 다운그레이드 했더니 너무나 잘되었다....
(내 버전은 1.4.5-lts.1이었음 ㅠ)
이렇게 허무하게 이슈를 해결할 때마다 어마무시한 현타를 맞게 됨 흑흑

결론: multer 버전을 다운그레이드 하면 된다!
'개발.ZIP' 카테고리의 다른 글
[Javascript] reduce 함수 완벽하게 이해하기.ZIP (0) | 2024.02.06 |
---|---|
[React+Typescript] Redux-Persist로 store 저장.ZIP (0) | 2024.01.31 |