인프런 커뮤니티 질문&답변
여러 사진 중 일부 사진의 허용 사이즈 초과로 실패한 경우에 대해
작성
·
18
1
안녕하세요 정환님! 항상 강의 감사한 마음으로 잘 듣고 있습니다. 이번 이미지 업로드 구현하기2 강의를 끝까지 듣고 따라하던중 스토리지에 이미지 업로드 병렬로 요청 시 제가 업로드 시도한 이미지 4장 중 1장이 허용 사이즈 초과로 스토리지 업로드 요청이 실패 했었는데요, 당연히 이미지 업로드 실패로
await deletePost(post.id);가 호출되 post.id를 받기위해 먼저 생성한 포스트가 삭제되어 포스트 자체가 안된것처럼 동작했습니다. 근데 storage에서는 업로드 요청이 실패된 이미지를 제외하고 나머지 3장의 이미지가 저장이 되어있더라고요!
간단하게 4장 병렬 이미지 업로드 요청 > 3장 성공 1장 실패 > 이미지 업로드 일부 실패로 포스트 삭제 > storage에는 성공한 3장의 이미지만 존재, 포스트는 없음
이 상태여서 혼자 찾아봐서 추가해봤는데 맞는지도 궁금하고 맞다면 다른 분들도 비슷한 상황에서 도움이 될까 싶어 올립니다!!
images.ts 파일에 스토리지에서 이미지 삭제하는 비동기 요청 함수
export async function deleteImages(filePath: string[]) {
const { data, error } = await supabase.storage
.from(BUCKET_NAME)
.remove(filePath);
if (error) throw error;
return data;
}
post.ts > createPostWithImages 함수 에서 try, catch문 밖에 업로드전 생성한 filePath 저장할 배열 값을 갖는 변수 선언
const uploadedFilePaths: string[] = [];
const imageUrls = await Promise.all(
images.map((image) => {
const fileExtension = image.name.split(".").pop() || "webp";
const fileName = `${Date.now()}-${crypto.randomUUID()}.${fileExtension}`;
const filePath = `${userId}/${post.id}/${fileName}`;
uploadedFilePaths.push(filePath);
return uploadImage({
file: image,
filePath,
});
}),
);uploadImage 리턴 전에 생성한 filePath값 저장
catch문에서
if (uploadedFilePaths.length > 0) {
await deleteImages(uploadedFilePaths);
}조건문 추가
최종 결과
병렬 요청중 일부의 요청이 파일의 크기 초과 등으로 실패하면
throw error >
await deletePost(post.id);
if (uploadedFilePaths.length > 0) {
await deleteImages(uploadedFilePaths);
}
throw error;
포스트 삭제, 스토리지 이미지 삭제
글을 잘 못써서 가독성이 떨어지는 부분은 양해부탁드립니다..
답변 2
0
반영 코드 도움되시는분 있으실까 첨부합니다
export async function createPostWithImages({
content,
images,
userId,
}: {
content: string;
images: File[];
userId: string;
}) {
// 1. 새로운 포스트 생성
const post = await createPost(content);
if (images.length === 0) return post;
const uploadedFilePaths: string[] = [];
try {
// 2. 이미지 업로드
const imageUrls = await Promise.all(
images.map((image) => {
const fileExtension = image.name.split(".").pop() || "webp";
const fileName = `${Date.now()}-${crypto.randomUUID()}.${fileExtension}`;
const filePath = `${userId}/${post.id}/${fileName}`;
uploadedFilePaths.push(filePath);
return uploadImage({
file: image,
filePath,
});
}),
);
// 3. 포스트 테이블 업데이트
const updatedPost = await updatePost({
id: post.id,
image_urls: imageUrls,
});
return updatedPost;
} catch (error) {
await Promise.all([
deletePost(post.id),
uploadedFilePaths.length > 0
? deleteImages(uploadedFilePaths)
: Promise.resolve(),
]);
throw error;
}
}0
안녕하세요 재환님 이정환입니다.
앗! 그렇네요 🥲 이런 이슈가 있을 수 있겠군요
해당 이슈를 해결하려면 재환님이 말씀해주신 대로 catch 문에서 업로드 된 이미지 전체를 삭제하는 로직을 추가해주시면 됩니다!
한가지 코멘트를 남기자면 await deletePost와 await deleteImages는 Promise.all을 통해 묶어 병렬처리하면 더 깔끔할 것 같아요!





더 깔끔한 방법 알려주셔서 감사합니다!!