error-repoting.txt 5.34 KB
* 개발 중 발생한 각종 오류에 관한 해결책을 담은 파일

- 1. Prisma 2 migration error ("There are more migrations in the database than locally ~")

https://stackoverflow.com/questions/60691027/prisma2-migrate-error-there-are-more-migrations-in-the-database-than-locally

원인
: DB 의 migration 과 prisma 의 migration 이 서로 불일치 할 때 나타나는 현상

위 원인이 발생하는 상황은 다음의 루트를 따랐기 때문에 발생한다고 볼 수 있다.

1. create migration
: prisma2 migrate save --name "init" --experimental
(Migration 생성)

2. execute migration
prisma2 migrate up --experimental
(migration 실행)

3. delete migration file in prisma/migrations 
(prisma 내부 migrations 폴더내의 migration 관련 파일 삭제)

4. try to run below command
prisma2 migrate save --name "new-migration" --experimental


이 프로젝트의 경우엔
처음에 도커 컨테이너를 생성하고 나서, 
prisma migrate 로 migration 을 생성해서 이미 관련된 로그 기록이 존재함
DB 의 migration 과 Backend 의 migration 이 서로 일치하지 않아서 생기는 문제 같은데
도커 컨테이너를 지우고 다시 실행하는게 가장 빠른 해결책
(근데 어떨때는 또 migration 이 서로 맞을 때도 있음)


- 2. Resolver Mapping 문제

https://stackoverflow.com/questions/62014031/graphql-always-return-null

원인
: merge-graphql-schemas 모듈을 활용하여 mergeResolvers 함수를 수행할때, 
Resolver 형태의 파일이 아닌 다른 형태의 파일이 끼어서, Mapping 이 정상적으로 작동하지 않는 경우

merge 를 할 대상에 속하는 모든 관련 파일들은 전부 Resolver 의 형태를 갖추고 있어야만함.
다른 종류의 파일이 오게 되면, mergeResolver 함수의 리턴 결과가 객체가 아닌 함수로 반환되기 때문에

GraphQL Playground 에서 쿼리문을 실행할때 항상 null 값으로 반환됨

그러므로, 반드시 api 폴더내에는 항상 형식에 맞는 파일만 와야함.


- 3. React Hook 의 종속성

React Hook "useQuery" is called in function "onSubmit" which is neither a React function component or a custom React Hook function

이런 오류가 뜰 경우,
react Hook 을 리액트 함수 컴포넌트나 리액트 훅이 아닌 다른 함수 내에서 사용하게 될때
발생하는 오류이다.
리액트 훅은 반드시 리액트로 만든 함수 컴포넌트 내부나 혹은 개발자가 직접 제작한 리액트 훅 내부에서만 사용가능하다.

- 4. React Hook 의 랜더링 순서

Rendered more hooks than during the previous render

이런 오류가 뜨는 경우, 리액트 훅이 랜더링 되는 시기에 undefined 혹은 null 인 데이터가 랜더링 되었기 때문에 발생한다.
React Hook 을 사용할 때는 몇가지 규칙이 있다.
(참고 : https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level)

가장 기본적으로 hook 은 어떤 조건문 이나, 반복문 등 에서 사용되선 안된다.
어떤 함수 내부적으로 소속된 형식에서 hook 을 쓰는 것이 아닌 hook 은 항상 top-level 에 존재해야한다.

- 5. WS 과 HTTP 
GraphQL Yoga 에는 자체적인 Websocket 기능과 HTTP 기능이 동시에 들어 있다
그래서 GraphQL Yoga 를 통해서 BE Server 를 테스트 할때,
별도의 설정을 하지 않아도 쿼리 구문만 잘 작성하면 Subscription 이 별 문제없이 실행되었다.
그러나 FE Server 와 BE 를 통합시킬때는 다르다.
FE 는 이 프로젝트에서 React 만을 사용하였기 때문에, 자체적인 WS 기능이 없다
그래서 Apollo 를 통해서 React 와 BE 가 서로 연결되어야 한다
하지만, BE 는 이 프로젝트에서 두 가지 네트워크 (WS, HTTP) 를 동시에 가지기 때문에,
Apollo-boost 에서 제공하는 Apollo-Client 만으로는 이 두개를 동시에 커버하기 어렵다.
(Apollo-Boost 의 Client 는 link 에 대한 설정 값이 없다,
좀 더 low-level 로 접근 해야 하기 때문에 Apollo-Client 모듈에서 불러와야 한다.
참조 : https://www.apollographql.com/docs/react/migrating/boost-migration/)

그래서, apollo-boost 대신에 apollo-client 모듈로 접근을 해야 하며,
이 프로젝트에서 고려해야할 옵션 사항으로는
1. 캐시 메모리를 사용하는 것
2. Request Header 를 사용할 수 있어야 하는 것.
3. link 값을 부여해줄 수 있어야 하는것
4. client State 를 사용할 수 있어야 하는 것
을 선정할 수 있다.

캐시 메모리는 
import { InMemoryCache } from "apollo-cache-inmemory";
이 모듈로 해결하고

Header 는 
const request = async (operation) => {
  const token = await AsyncStorage.getItem('token');
  operation.setContext({
    headers: {
      authorization: token
    }
  });
};

로 잡아주고

3. link 값은 

const httpLink = new HttpLink({
  uri: "http://localhost:4000/",
});

const wsLink = new WebSocketLink({
  uri: "ws://localhost:4000/",
  options: {
    reconnect: true,
  },
});

const terminatingLink = split(
  ({ query: { definitions } }) =>
    definitions.some((node) => {
      const { kind, operation } = node;
      return kind === "OperationDefinition" && operation === "subscription";
    }),
  wsLink,
  httpLink
);
값으로 처리하며,

4. 마지막 client state 는
import { withClientState } from 'apollo-link-state';
모듈을 이용한다.