프로젝트를 다른 컴퓨터로 옮기는 과정에서 겪은 문제이다.
분명 같은 코드, DB 상태도 동일한데 로그인할때 401에러가 발생했다.
서버에서 에러가 터지지도 않았고, user 테이블에도 데이터가 있었다.
그렇게 헬 게이트 시작...
며칠 동안 헤매던 끝에 발견한 원인은 의외로 간단했다.
너무나도 어처구니 없을 정도로...
그럼에도 이 내용을 블로그에 남기는 이유는, 문제가 너무 단순해서 되려 원인을 파악하기 어려웠기 때문이다. 누군가 비슷한 상황에서 해결의 실마리를 얻을 수 있기를 바란다.
프로젝트 경로에 '특수 문자'나 '괄호'가 포함되어있는지 확인해보자!
.../[폴더명]/프로젝트/server/...
허탈하게도 프로젝트를 clone한 위치가 문제였다.
서버 에러도 없이 401이 뜨는데 경로 문제였다니 생각도 못했다...😅
< 1 > mysql 버전 체크
인증 실패니까 제일 먼저 확인했던게 DB.
문제의 컴퓨터는 최근에 mysql을 설치했고, 현재 지원되지 않는 mysql 구버전(5.7.44)을 사용했던 상황이라 MySQL 8.0 시리즈로 바꿀 수 밖에 없었다. 하필 설치할때 문제가 발생했고, 완전히 지워지지 않는 이슈 때문에 재설치도 잘 안되서 한참 애먹었다. 그리고 gpt가 완전히 호환되지는 않는다고 덧붙이길래 이 문제를 의심했다.
코드는 동일하니 버전문제인건가 싶었고, 이것저것 체크해보다가 배포 중인 EC2 인스턴스의 mysql 버전을 확인했다. 다행히도 동일한 버전을 사용하는 걸로 보아 버전 이슈는 배제되었다.
< 2 > api 함수 체크
필자는 NestJS를 사용해본적이 없어서 서버가 실행되는 흐름을 잘 모르지만, 프론트엔드 개발자로 일하면서 종종 응답 에러가 발생하면 해당 요청에 서버 코드를 확인해보곤했다.
이 프로젝트 에러의 시작점은 로그인이였으니 api로 호출되는 함수를 확인해보았다. console.log()가 찍히지 않는다. 401로 응답이 왔지만 해당 함수에 접근조차 하지 않았던 것이다.
< 3 > DB 연결 체크
mysql 버전 문제는 제외시켰지만 그래도 서버 연결이 되었는지 체크를 해봐야했다. gpt가 짜준 코드를 조금 변형해서 쿼리로 데이터를 확인했다. 확실히 DB 문제는 아닌걸 확인했다.
import { Injectable, OnModuleInit } from '@nestjs/common';
import { DataSource } from 'typeorm';
@Injectable()
export class DatabaseService implements OnModuleInit {
constructor(private readonly dataSource: DataSource) {}
async onModuleInit() {
if (this.dataSource.isInitialized) {
console.log('✅ Database connected successfully!');
this.checkConnection();
} else {
console.error('❌ Database connection failed!');
}
}
async checkConnection(): Promise<boolean> {
try {
const temp = await this.dataSource.query('SELECT email from users'); // 간단한 쿼리 실행 테스트
console.log('테스트', temp);
return true;
} catch (error) {
console.error('❌ Database connection error:', error);
return false;
}
}
}
< 4 > 에러 메세지 찾기
네트워크 401에러 외에는 어디가 문제인지 알 수가 없었다. 어디부터 봐야할지 감도 안오다가 접근 가능한 회원가입 페이지에서 다른 api 요청을 보내봤다. 드디어 제목처럼 서버 오류가 발생했다. 원흉은 엔티티이다.
EntityMetadataNotFound Error: No metadata for 'AuthCode' was found.
< 5 > 엔티티 연결 체크
에러 메세지를 보아 문제는 확실히 엔티티에서 발생하는거였다.
gpt가 여러 가능성을 알려주었고
1. AuthCode 엔티티 선언 확인
2. 엔티티 등록 누락 -> 위치 확인
3. @Entity() 적용
...
AuthCode 엔티티는 선언이 되어있었고, 가장 유력한 건 경로인데 파일경로(위 이미지에서 라임색상)는 문제가 없었다.
console.log(this.dataSource.entityMetadatas)
정상적으로 동작하는 컴퓨터와 달리 문제의 컴퓨터에서는 빈배열로 찍혔다. 등록 부분에서의 문제인 것 같지만, 요리조리 보아도 라임색 경로는 맞았다.
구글링 해보니 엔티티들을 import 해와서 직접 나열하기도 하는 것 같았다. 하지만 서버 코드를 잘 모르는 상태에서 임의로 변경하는건 다른 오류로 이어질수있으므로 최후의 수단이였다.
console.log(__dirname + '/**/entities/*.entity.{ts,js}')
// /Users/맥사용자이름/Desktop/폴더명/[폴더명]/프로젝트명/server/dist/src/**/entities/*.entity.{ts,js}
절대 경로 __dirname ...
정렬했을때 가장 먼저 보이게 하려고 '특수문자'나 '괄호'를 붙이는데 이게 원인이였다. 설마하는 마음에 폴더명을 바꿨는데 바로 문제 해결!
git 관련 경로 변경할때, 동적 파라미터 /[id]
에도 대괄호를 사용하니까 괜찮은줄 알았는데 아니였다...그렇게 험난한 에러 찾기가 끝났다.
장황하게 시행착오를 나열한 것처럼, 이번 오류는 역대급으로 해결하기 힘들었다.
혼자서 포기하지 않고 끝까지 문제를 해결했다는 기쁨과 동시에, 들인 시간/노력과는 반대로 너무나도 쌩뚱맞은 곳에서 원인을 발견하니 조금 허탈했다.
이 글을 본 사람들은 이런 고생을 덜하길 바란다.
그리고,
컴퓨터는 거짓말을 하지 않는다.🙂↔️