Skip to content

Commit 941443f

Browse files
committed
CLAP-310 Refactor: 예외 처리 추가
<footer> - 관련: #380
1 parent a16da66 commit 941443f

File tree

6 files changed

+42
-22
lines changed

6 files changed

+42
-22
lines changed

src/main/java/clap/server/adapter/outbound/infrastructure/clamav/ClamAVScanner.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package clap.server.adapter.outbound.infrastructure.clamav;
22

3+
import clap.server.exception.ClamAVException;
4+
import clap.server.exception.code.FileErrorcode;
35
import lombok.RequiredArgsConstructor;
46
import lombok.extern.slf4j.Slf4j;
57
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -20,10 +22,10 @@
2022
@Component
2123
@RequiredArgsConstructor
2224
public class ClamAVScanner {
23-
private final ClamavClient client;
25+
private final ClamavClient clamavClient;
2426
private final ThreadPoolTaskExecutor clamavExecutor;
2527

26-
public CompletableFuture<Boolean> scanFileAsync(String filePath) {
28+
public CompletableFuture<Void> scanFileAsync(String filePath) {
2729
return CompletableFuture.supplyAsync(() -> {
2830
Path originalPath = Paths.get(filePath);
2931
Path tempPath = null;
@@ -35,25 +37,23 @@ public CompletableFuture<Boolean> scanFileAsync(String filePath) {
3537

3638
Files.copy(originalPath, tempPath, StandardCopyOption.REPLACE_EXISTING);
3739

38-
ScanResult result = client.scan(tempPath);
40+
ScanResult result = clamavClient.scan(tempPath);
3941
if (result instanceof ScanResult.OK) {
4042
log.info("파일이 안전합니다: {}", originalFileName);
41-
return true;
4243
} else if (result instanceof ScanResult.VirusFound virusFound) {
4344
log.warn("바이러스 발견: {} in {}", virusFound.getFoundViruses(), originalFileName);
44-
return false;
45+
throw new ClamAVException(FileErrorcode.VIRUS_FILE_DETECTED);
46+
} else {
47+
log.warn("알 수 없는 스캔 결과 타입: {}", result.getClass().getName());
48+
throw new ClamAVException(FileErrorcode.FILE_SCAN_FAILED);
4549
}
46-
log.warn("알 수 없는 스캔 결과 타입: {}", result.getClass().getName());
47-
return false;
50+
return null;
4851
} catch (IOException e) {
4952
log.error("파일 처리 중 오류 발생: {}", filePath, e);
50-
return false;
53+
throw new ClamavException(e);
5154
} catch (ClamavException e) {
5255
log.error("ClamAV 스캔 중 오류 발생: {}", filePath, e);
53-
return false;
54-
} catch (Exception e) {
55-
log.error("예상치 못한 오류 발생: {}", filePath, e);
56-
return false;
56+
throw new ClamavException(e);
5757
} finally {
5858
if (tempPath != null) {
5959
try {

src/main/java/clap/server/adapter/outbound/infrastructure/clamav/FileVirusScanner.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package clap.server.adapter.outbound.infrastructure.clamav;
22

33
import clap.server.exception.AdapterException;
4+
import clap.server.exception.ClamAVException;
45
import clap.server.exception.code.FileErrorcode;
56
import lombok.RequiredArgsConstructor;
67
import lombok.extern.slf4j.Slf4j;
@@ -16,6 +17,7 @@
1617
import java.util.List;
1718
import java.util.Objects;
1819
import java.util.concurrent.CompletableFuture;
20+
import java.util.concurrent.ExecutionException;
1921
import java.util.stream.Collectors;
2022

2123
@Slf4j
@@ -37,6 +39,10 @@ public List<MultipartFile> scanFiles(List<MultipartFile> files) {
3739
.collect(Collectors.toList());
3840
}
3941

42+
public MultipartFile scanSingleFile(MultipartFile file) throws ExecutionException, InterruptedException {
43+
return scanFile(file).get();
44+
}
45+
4046
@Async("clamavExecutor")
4147
protected CompletableFuture<MultipartFile> scanFile(MultipartFile file) {
4248
return CompletableFuture.supplyAsync(() -> {
@@ -46,14 +52,11 @@ protected CompletableFuture<MultipartFile> scanFile(MultipartFile file) {
4652
try (InputStream inputStream = file.getInputStream()) {
4753
Files.copy(inputStream, tempPath, StandardCopyOption.REPLACE_EXISTING);
4854
}
49-
50-
boolean isSafe = clamAVScanner.scanFileAsync(tempPath.toString()).get();
51-
if (isSafe) {
52-
return file;
53-
} else {
54-
log.warn("Virus detected in file: {}", file.getOriginalFilename());
55-
throw new AdapterException(FileErrorcode.VIRUS_FILE_DETECTED);
56-
}
55+
clamAVScanner.scanFileAsync(tempPath.toString()).get();
56+
return file;
57+
} catch (ClamAVException e) {
58+
log.warn("Virus detected in file: {}", file.getOriginalFilename());
59+
throw new AdapterException(FileErrorcode.FILE_SCAN_FAILED);
5760
} catch (Exception e) {
5861
log.error("Failed to scan file: {}", file.getOriginalFilename(), e);
5962
return null;

src/main/java/clap/server/adapter/outbound/infrastructure/clamav/FileVirusScannerPort.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import org.springframework.web.multipart.MultipartFile;
44

55
import java.util.List;
6+
import java.util.concurrent.ExecutionException;
67

78
public interface FileVirusScannerPort {
89
List<MultipartFile> scanFiles(List<MultipartFile> files);
10+
MultipartFile scanSingleFile(MultipartFile file) throws ExecutionException, InterruptedException;
911
}

src/main/java/clap/server/application/service/task/CreateTaskService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public CreateTaskResponse createTask(Long requesterId, CreateTaskRequest createT
5656
}
5757

5858
@Override
59+
@Transactional
5960
public CreateTaskResponse createTaskWithScanner(Long requesterId, CreateTaskRequest createTaskRequest, List<MultipartFile> files) {
6061
Member member = memberService.findActiveMember(requesterId);
6162
Category category = categoryService.findById(createTaskRequest.categoryId());
@@ -73,7 +74,7 @@ public CreateTaskResponse createTaskWithScanner(Long requesterId, CreateTaskRequ
7374
}
7475

7576
private void saveAttachments(List<MultipartFile> files, Task task) {
76-
List<String> fileUrls = s3UploadPort.uploadFiles(FilePathPolicy.TASK_IMAGE, files);
77+
List<String> fileUrls = s3UploadPort.uploadFiles(FilePathPolicy.TASK_FILE, files);
7778
List<Attachment> attachments = AttachmentMapper.toTaskAttachments(task, files, fileUrls);
7879
commandAttachmentPort.saveAll(attachments);
7980
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package clap.server.exception;
2+
3+
import clap.server.exception.code.BaseErrorCode;
4+
5+
public class ClamAVException extends BaseException {
6+
public ClamAVException(BaseErrorCode code) {
7+
super(code);
8+
}
9+
10+
public BaseErrorCode getErrorCode() {
11+
return (BaseErrorCode)super.getCode();
12+
}
13+
}

src/main/java/clap/server/exception/code/FileErrorcode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
public enum FileErrorcode implements BaseErrorCode {
1010
FILE_UPLOAD_REQUEST_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FILE_001", "파일 업로드에 실패하였습니다."),
1111
UNSUPPORTED_FILE_TYPE(HttpStatus.BAD_REQUEST, "FILE_002", "유효하지 않은 파일 유형입니다."),
12-
VIRUS_FILE_DETECTED(HttpStatus.BAD_REQUEST, "FILE_003", "안전하지 않은 파일이 감지되었습니다.")
12+
VIRUS_FILE_DETECTED(HttpStatus.BAD_REQUEST, "FILE_003", "안전하지 않은 파일이 감지되었습니다."),
13+
FILE_SCAN_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FILE_004", "파일 스캔에 실패하였습니다.")
1314
;
1415

1516
private final HttpStatus httpStatus;

0 commit comments

Comments
 (0)