BadMapError

BadMapError

맵(map)이 기대되는 자리에 다른 값이 들어왔을 때 던져지는 예외예요. Elixir에서 맵 전용 연산자(예를 들어 업데이트 연산자 |)를 쓰면 런타임이 대상이 진짜 맵인지 확인하는데, 그게 아니면 이 예외가 발생해요.

출처: BadMapError (Elixir v1.20.4)

본문

예를 들어 문자열 "hello"에 업데이트 연산자 |를 쓰면 어떻게 될까요.

iex> value = "hello"
iex> %{value | key: "value"}
** (BadMapError) expected a map, got:
...

에러 메시지가 "맵이 와야 하는데, 이 값을 받았다"고 알려줘요. %{value | key: "value"}value라는 맵의 key 필드를 새 값으로 바꾸는 문법인데, value가 맵이 아니라서 예외가 터진 거예요.

이 예외는 맵 전용 문법을 다른 타입에 적용했을 때 주로 나와요. 대표적인 경우는 다음과 같아요.

  • 맵 업데이트 문법 %{map | key: value}를 맵이 아닌 값에 사용할 때
  • 맵 패턴 매칭에서 오른쪽에 맵이 아닌 값이 올 때
  • 구조체(struct)를 기대하는 함수에 맵이 아닌 값이나 다른 종류의 값을 넘길 때

구조체도 내부적으로는 맵이기 때문에, 구조체 필드를 업데이트할 때도 같은 연산자 |를 써요. 그래서 이 예외는 "맵이나 구조체가 와야 하는 자리에 딴 게 왔다"는 신호로 이해하면 돼요.

문제를 고치려면, 대상 값이 정말 맵인지 is_map/1으로 확인해 보거나, 어디서 값이 바뀌었는지 추적해 보는 게 좋아요. 변수에 맵을 담아뒀다고 생각했는데 그 사이에 다른 값으로 재할당됐을 수도 있거든요.

더 알아보기