Protocol.UndefinedError 예외
Protocol.UndefinedError 예외
프로토콜이 어떤 값에 대해 구현되어 있지 않을 때 던져지는 예외예요. Elixir에서 프로토콜은 "이 동작을 구현한 타입이면 이 함수를 쓸 수 있어요"라고 약속하는 일종의 계약인데, 아직 그 계약을 지키지 않은 타입에 프로토콜 함수를 호출하면 이 예외를 만나게 됩니다.
가장 자주 보는 경우가 바로 컬렉션 함수입니다. 예를 들어 Enum.at/2는 Enumerable 프로토콜을 필요로 하는데, 문자열(BitString)은 Enumerable을 구현하지 않아서 다음과 같이 예외가 발생해요.
본문
iex> Enum.at("A string!", 0)
** (Protocol.UndefinedError) protocol Enumerable not implemented for BitString
...
이 예외의 다음 필드는 공개되어 있어서 field(...)나 예외 인스턴스에서 자유롭게 읽을 수 있어요.
:protocol(module/0) — 구현되어 있지 않은 프로토콜. 어떤 프로토콜의 함수를 호출했는지를 알려줍니다.:value(term/0) — 해당 프로토콜을 구현하지 않는 값. 어떤 값 때문에 실패했는지를 담고 있죠.
이 두 필드는 예외를 잡아서 친절한 오류 메시지로 다시 던지거나, 로깅할 때 특히 유용합니다. 예를 들어 디버깅할 때 e.protocol과 e.value를 찍어보면 어느 프로토콜이 어느 값 때문에 터졌는지 바로 확인할 수 있어요.
이 예외를 없애는 방법은 크게 두 가지입니다. 하나는 그 타입에 맞는 다른 함수를 쓰는 것(위 예시처럼 문자열에는 Enum 대신 String이나 :binary 모듈을 쓰는 것), 다른 하나는 필요하다면 해당 타입에 프로토콜 구현을 추가하는 것입니다.
더 알아보기
Protocol— 프로토콜의 정의·구현·컴파일 동작을 다루는 공식 문서Enumerable— 컬렉션 순회와 관련된 프로토콜의 명세Enum—Enumerable프로토콜을 기반으로 동작하는 컬렉션 함수 모듈String— 문자열 처리를 위한 모듈 (Enum.at/2대신 쓸 수 있어요)