1. Next.js 어플리케이션 ECS 컨테이너 로그에 동일로그 반복적인 발생
- [RangeError] : Incorrect locale information provided
2. 로그를 통해 원인 추정
Error [RangeError]: Incorrect locale information provided
at Intl.getCanonicalLocales (<anonymous>)
- Intl.getCanonicalLocales는 국제화 API (Intl)에서 사용되며, 브라우저 또는 Node.js에서 locale string이 유효한지 검사할 때 호출된다.
- 이 함수에 잘못된 locale 문자열(예: en_kr 혹은 undefined, 123)이 들어오면 RangeError가 발생.
- 발생 위치 : file:///application/.next/server/middleware.js:13:82575
- 미들웨어 동작에서 이슈 추정
3. middleware 에서 어디?
- 미들웨어의 request 로 부터 헤더에서 로케일 정보를 뽑아내는 getLocale 함수를 의심
const languages = new Negotiator({ headers: negotiatorHeaders }).languages();
const locale = match(languages, LocalePool, defaultLocale);
- Negotiator를 통해 헤더에서 언어 목록을 추출하고
- match 함수로 사전에 정의한 LocalePool에서 가장 적절한 locale을 선택함
- ⚠️ 그런데 Negotiator().languages()는 Accept-Language 헤더가 malformed일 경우 다음을 리턴할 수 있음:
- "invalid-locale" 형태의 이상한 문자열
- 또는 ["*", "zz", "123"] 같이 RFC 5646에 맞지 않는 문자열들
- 즉, 입력값이 비정상이라면 match() 함수에서 내부적으로 Intl.getCanonicalLocales()를 호출하면서 RangeError를 발생시킬 수 있음.
- match() 함수는 @formatjs/intl-localematcher 패키지로 부터 가져와서 사용하고 있는데, 해당 페키지에는 에러로그의 일부인 at Intl.getCanonicalLocales (<anonymous>) 함수도 있음
- match() 함수에서 발생한 에러임을 확인
4. 어떻게 수정?
- match() 함수에서 에러가 발생하면, 패키지 내부적으로 어찌 동작하는지 모르니, try-catch 로 감싸서 defaultLocale 로 세팅한다
- 사실상 match() 함수의 기대 동작이 찾는 값이 LocalePool 에 없으면 defaultLocale 로 세팅하는 것인데, 타입이 안맞아서 인지.. 원하는 대로 동작을 안하는 것 같다.
5. 동작 테스트
- Postman 으로 헤더에 로케일 정보가 없는 api를 날린다
- new Negotiator 로 뽑은 languages 값이 match() 함수에서 비정상 동작을 일으켜, catch 로 떨어지고, 이에 따라 locale 이 default 인 kr-ko 로 세팅됨
- defaultLocale 로 세팅되어 정상 리턴 확인
'programming > error' 카테고리의 다른 글
An invalid form control with name='' is not focusable. (0) | 2022.09.23 |
---|