File.CopyError 예외
File.CopyError 예외
파일이나 디렉터리를 복사하는 작업이 실패했을 때 발생하는 예외예요. 복사 대상이나 목적지가 제대로 준비되어 있지 않으면 이 예외가 떠요.
예를 들어 존재하지 않는 파일을 재귀적으로 복사하려고 하면 다음처럼 에러가 나요.
iex> File.cp_r!("non_existent", "source_dir/subdir")
** (File.CopyError) could not copy recursively from "non_existent" to "source_dir/subdir". non_existent: no such file or directory
본문
File.cp_r/3나 File.cp_r!/3처럼 재귀적으로 복사하는 함수는, 원본 파일이 존재하지 않거나 목적지 디렉터리가 없을 때 이 예외를 던져요. 이름에 느낌표가 붙은 버전(!)은 실패 시 예외를 던지고, 느낌표가 없는 버전은 {:ok, ...} / {:error, ... 튜플로 돌려주는 차이를 기억해 두면 좋아요.
이 예외는 문제를 분석하기 쉽도록 여러 공개 필드를 제공해요. 이 필드들은 자유롭게 접근해서 사용할 수 있어요.
:source(Path.t/0) — 복사하려는 원본 경로예요.:destination(Path.t/0) — 복사가 도착해야 할 목적지 경로예요.:reason(File.posix/0) — 파일을 복사하지 못한 이유예요.
에러를 받아서 어디에서 문제가 생겼는지, 왜 실패했는지를 로그로 남기거나 사용자에게 보여줄 때 이 필드들이 유용하게 쓰여요.
실무에서 이 예외를 마주하는 순간은 보통 두 가지예요. 한 가지는 원본 경로에 파일이 실제로 없는 경우이고, 다른 한 가지는 목적지 디렉터리가 만들어져 있지 않은 경우예요. 특히 재귀 복사(cp_r)는 여러 경로를 오가기 때문에, 어떤 경로가 어디까지 진행됐는지 추적하기가 쉽지 않아요. 그래서 이 예외가 던져지면 :source와 :destination 필드를 살펴 "원본이 없어서인지, 목적지가 없어서인지"를 먼저 좁혀 보는 게 좋아요. 경우에 따라 목적지 디렉터리를 미리 만들어 두면 해결될 때도 있어요.
복사 실패를 우아하게 처리하고 싶다면 느낌표가 없는 File.cp/3 계열을 써서 {:error, reason}을 받는 것도 방법이에요. 실패가 흔할 수 있는 상황이라면 예외에만 의존하기보다, 반환값으로 분기하는 방식이 더 다루기 편할 수 있어요.
더 알아보기
File.cp_r/3와File.cp_r!/3의 차이(튜플 반환 vs 예외 발생)를 함께 확인해 보세요.- 원본 경로 해석에 대한 자세한 내용은
Path모듈 문서를 참고해요. - 파일 작업 전반의 오류 구조를 이해하려면
File모듈과File.posix/0타입을 함께 보면 좋아요.