프로젝트/날씨 칵테일

[프로젝트] 날씨 칵테일 | 트러블슈팅- SyntaxError: Unexpected token '<', "<br /> <b>"... is not valid JSON

paintover23 2023. 10. 16. 16:53
728x90

 

(진행배경) cocktail 정보를 Open API를 통해 렌더링함에 그간 문제가 없었는데 어느날은 SyntaxError가 발생하였다. 코드를 고치지 않았는데도 문제가 발생한 것으로 보아 일단은 CocktailDB 서버 자체 문제로 간주되었다. 혹여 클라이언트의 문제인지 체크하기 위해 아래와 같이 API 주소를 주소창에 직접 입력해보니 데이터베이스 연결에 실패하고 있다는 에러 메세지를 반환하였다.

https://www.thecocktaildb.com/api/json/v1/1/filter.php?g=Coffee_mug

 

[문제-SyntaxError: Unexpected token '<', "<br /> <b>"... is not valid JSON]

(문제원인) SyntaxError: Unexpected token '<', "<br /> <b>"... is not valid JSON 이 에러는 주어진 데이터가 올바른 JSON 형식이 아닐 발생한다. "<br /> <b>" 같은 HTML 태그가 포함되어 있기 때문에 JSON 파싱에 실패한 것이다. 캡쳐된 에러 메시지를 분석해보면, 웹 페이지에서 데이터베이스 연결에 실패하고 있으며, 이로 인해 발생하는 에러 메시지들이 JSON 형식이 아닌 HTML 형식으로 반환되고 있다. 이러한 HTML 형식의 에러 메시지를 JSON으로 해석하려 할 때 위와 같은 에러가 발생하게 된다. 실제로 header의 content-type을 살펴보니 text/html 형식으로 반환되고 있었다., 원인은 데이터베이스 연결 문제로 인해 HTML 형식의 에러 메시지가 반환되었고, 이를 JSON으로 해석하려 했기 때문에 발생한 문제이다.

 

(해결방법) 이와 같이 Open API 서버에서 발생하는 에러로 인한 렌더링 이슈를 방지 하기 위해 서버가 반환하는 header의 content type이 application/json 형식인지 1차로 확인해보고 그것이 맞을 때만 렌더링 되도록 하는 예외처리 로직을 추가하였다.

// CocktailAPI > index.ts
// [수정 전]

export async function getGlassTypeAPI(glassType: string) {
  try {
    const response = await fetch(
      `https://www.thecocktaildb.com/api/json/v1/1/filter.php?g=${glassType}`
    );
    if (!response.ok) {
      throw new Error(
        `칵테일 데이터를 가져오는 데 실패했습니다: ${response.statusText}`
      );
    }
      const data = await response.json();
      const cocktailArr = data.drinks;
      return cocktailArr;
  } catch (error) {
    console.error(
      '서버와 통신에 실패하였습니다. 나중에 다시 시도해주세요.',
      error
    );
    throw error;
  }
}
// CocktailAPI > index.ts
// [수정 후]

export async function getGlassTypeAPI(glassType: string) {
  try {
    const response = await fetch(
      `https://www.thecocktaildb.com/api/json/v1/1/filter.php?g=${glassType}`
    );
    if (!response.ok) {
      throw new Error(
        `칵테일 데이터를 가져오는 데 실패했습니다: ${response.statusText}`
      );
    }
    // 예외처리 로직 추가
    if (response.headers.get('content-type')?.includes('application/json')) {
      // const contentType = response.headers.get('content-type');
      // console.log('contentType', contentType); // application.json
      const data = await response.json();
      const cocktailArr = data.drinks;
      return cocktailArr;
    } else {
      console.error(
        '서버로부터 예상치 못한 응답을 받았습니다. 나중에 다시 시도해 주세요.'
      );
    }
  } catch (error) {
    console.error(
      '서버와 통신에 실패하였습니다. 나중에 다시 시도해주세요.',
      error
    );
    throw error;
  }
}

 

(배운점) 서버에서 잘못된 응답은 html을 반환한다는 사실과 이를 json 형식으로 해석하려고 할 때 발생하는 에러임을 알게되었다.

728x90
반응형