Apollo-link: networkError [apollo-link-error]에 λŒ€ν•œ 응닡 ν•„λ“œκ°€ μ •μ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2018λ…„ 11μ›” 06일  Β·  29μ½”λ©˜νŠΈ  Β·  좜처: apollographql/apollo-link


onError ν•¨μˆ˜λ‚˜ λ¬Έμ„œμ— 버그가 μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. 이 λ¬Έμ œλŠ” #698μ—μ„œ 이미 μ–ΈκΈ‰λ˜μ—ˆμ§€λ§Œ 해결을 μœ„ν•΄ 쑰금 더 ꡬ체화해야 ν•œλ‹€κ³  μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

apollo-boost μ—μ„œ λ˜λŠ” apollo-link-error μ—μ„œ 직접 onError λ₯Ό μ‚¬μš©ν•˜μ—¬ 였λ₯˜λ₯Ό κ°€λ‘œμ±Œ λ•Œ λ¬Έμ„œ μ—λŠ” 였λ₯˜ κ°œμ²΄μ— λ‹€μŒμ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆλŠ” response κ°œμ²΄κ°€ ν¬ν•¨λ˜μ–΄ μžˆλ‹€κ³  λ‚˜μ™€ μžˆμŠ΅λ‹ˆλ‹€. 였λ₯˜λ₯Ό λ¬΄μ‹œν•©λ‹ˆλ‹€.

이것은 μ˜λ„λœ λ™μž‘μΌ 수 있기 λ•Œλ¬Έμ— λ¬Έμ„œ ν™•μΈλž€μ„ ν‘œμ‹œν–ˆμ§€λ§Œ λ¬Έμ„œμ—μ„œ networkError μ„Ήμ…˜μ˜ ν•˜μœ„ λ‹¨λ½μ—μ„œ response 개체λ₯Ό μ–ΈκΈ‰ν•˜λ―€λ‘œ λ‹€μŒκ³Ό 같은 경우 μ•½κ°„ λͺ…ν™•νžˆ ν•΄μ•Ό ν•©λ‹ˆλ‹€. 경우.

μ˜ˆμƒλ˜λŠ” λ™μž‘
response.errors = null; λ₯Ό μ„€μ •ν•˜λ©΄ λ‹€λ₯Έ 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•Šκ³  였λ₯˜κ°€ μ „νŒŒλ˜λŠ” 것을 방지할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ‹€μ œ 행동
networkError λ₯Ό μž‘μ„ λ•Œ response ν•„λ“œκ°€ μ •μ˜λ˜μ§€ μ•Šμ•„ response.errors λ₯Ό μ„€μ •ν•˜λ €κ³  ν•  λ•Œ ꡬ문 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€. ν˜„μž¬λ‘œμ„œλŠ” λΆˆκ°€λŠ₯ν•œ 이유둜 이것은 μ‹€μ œλ‘œ λ„€νŠΈμ›Œν¬ 였λ₯˜κ°€ μ „νŒŒλ˜λŠ” 것을 λ°©μ§€ν•˜μ§€λ§Œ λŒ€μ‹  λ‹€λ₯Έ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€.

λ‚΄ μ„€μ •(MacOS 10.14.1 w. Chrome 70.0.3538.77) response.errors = null λ₯Ό μ„€μ •ν•˜λ©΄ Uncaught TypeError: Cannot set property 'errors' of undefined κ°€ λ°œμƒν•˜κ³  response = { errors: null } λŠ” Uncaught Error: "response" is read-only κ°€ λ°œμƒν•©λ‹ˆλ‹€.

skaermbillede 2018-11-06 kl 15 08 10

skaermbillede 2018-11-06 kl 15 09 20

_λ‹¨μˆœν•œ_ μž¬μƒμ‚°

λ‹€μŒμ€ apollo-boost λ₯Ό μ‚¬μš©ν•œ μž¬μƒμ‚°μž…λ‹ˆλ‹€. apollo-link-error λ₯Ό 직접 μ‚¬μš©ν•˜μ—¬λ„ 같은 λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€.

import ApolloClient from 'apollo-boost';

const client = ApolloClient({
  uri: '/my_api',
  onError: (({ response, networkError }) => {
    if (networkError && networkError.statusCode === 401) {
      console.log(response); // prints 'undefined'
      response.errors = null; // will throw 'undefined' error
      response = { errors: null }; // will throw a 'read-only' error 
    }
  })
});

이슈 라벨

  • [ ] μž¬μƒμ‚°
  • [ ] νŠΉμ§•
  • [x] λ¬Έμ„œ
  • [ ] 차단
  • [ ] 쒋은 첫 λ°œν–‰

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

이 λ¬Έμ œμ— 진전이 μžˆμŠ΅λ‹ˆκΉŒ?

λͺ¨λ“  29 λŒ“κΈ€

이 버그에 λŒ€ν•œ μž„μ‹œ ν•΄κ²° 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

+1 μ„œλ²„ ν™˜κ²½μ—μ„œ apollo ν΄λΌμ΄μ–ΈνŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” 경우 디버깅에 λŒ€ν•œ κ½€ 큰 λ¬Έμ œμž…λ‹ˆλ‹€(리쑸버에 λŒ€ν•΄ λ‹€λ₯Έ GraphQL μ„œλ²„μ—μ„œ 데이터 읽기).

+1
μ‘°κ±΄λΆ€λ‘œ 였λ₯˜λ₯Ό λ¬΄μ‹œν•˜λŠ” ν•΄κ²° 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

λ‚˜λŠ” λ˜ν•œμ΄ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜μ—κ²Œ 큰 λ¬Έμ œλŠ” 이것이 UIκ°€ 이 였λ₯˜λ₯Ό μΈμ‹ν•˜μ§€ λͺ»ν•˜κ²Œ ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ‹€μ œλ‘œ 큰 였λ₯˜κ°€ λ°œμƒν•˜λ©΄ λ‘œλ“œ μƒνƒœλ‘œ μœ μ§€λ©λ‹ˆλ‹€.

λ‚˜λŠ” 이것을 μ‘°μ‚¬ν–ˆκ³  λ¬Έμ„œμ— λ”°λ₯΄λ©΄ μ½œλ°±μ— μ‘λ‹΅ν•΄μ•Όν•©λ‹ˆλ‹€.
https://www.apollographql.com/docs/link/links/error.html#callback

일반 μ½œλ°±μ„ μ‚¬μš©ν•˜λ©΄ λ‹€μŒκ³Ό 같은 일이 λ°œμƒν•©λ‹ˆλ‹€ .

κ·ΈλŸ¬λ‚˜ networkError: https://github.com/apollographql/apollo-link/blob/master/packages/apollo-link-error/src/index.ts#L62

병합될 μ‹œκΈ°μ— λŒ€ν•œ 톡찰λ ₯이 μžˆμŠ΅λ‹ˆκΉŒ? :)

μ•„λ§ˆλ„ 곧, apollo νŒ€μ€ μƒˆλ‘œμš΄ ν΄λΌμ΄μ–ΈνŠΈμ™€ λ°˜μ‘ 버전을 μΆœμ‹œν•˜λŠ” 데 집쀑할 κ²ƒμž…λ‹ˆλ‹€.

이 λ¬Έμ œμ— 진전이 μžˆμŠ΅λ‹ˆκΉŒ?

이에 λŒ€ν•œ 진전이 μžˆλŠ”μ§€λ„ κΆκΈˆν•©λ‹ˆλ‹€. μ•„λ‹ˆλ©΄ κ·Έλ™μ•ˆμ˜ ν•΄κ²° 방법? APIμ—μ„œ UI둜 μ‚¬μš©μž μ •μ˜ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό μ „νŒŒν•˜λŠ” 방법을 κ°–κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” λ˜ν•œ 같은 λ¬Έμ œμ— μ§λ©΄ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λ₯Ό μœ„ν•œ ν•΄κ²° 방법은 빈 Observable을 λ°˜ν™˜ν•˜λŠ” κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ™Έλ₯Ό λ˜μ§€μ§€ μ•Šκ³  μ„œλ²„κ°€ 503에 μ‘λ‹΅ν•˜λŠ” 경우λ₯Ό λŒ€λΉ„ν•˜μ—¬ 쑰용히 μœ μ§€ νŽ˜μ΄μ§€λ‘œ λ¦¬λ””λ ‰μ…˜ν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ° λ‚΄ μ½”λ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ•„λ§ˆλ„ λˆ„κ΅°κ°€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

import { Observable } from 'apollo-link';

...

onError(({ networkError }: any) => {
      if (networkError && networkError.status === 503) {
        this.redirectService.goToMaintenance();
        return Observable.of();
      }
});

...

@ luki215 였λ₯˜ μ½”λ“œ ν•„λ“œκ°€ μ—†μŠ΅λ‹ˆλ‹€
image

@Sceat μ–΄λ–€ apollo-link 을 μ‚¬μš©ν•©λ‹ˆκΉŒ? λ‚˜λŠ” apollo-angular-link-http λ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ 차이가 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

@luki215 μ‹€μ œλ‘œ λ‚΄ 잘λͺ»μ΄μ—ˆμŠ΅λ‹ˆλ‹€. AWS api κ²Œμ΄νŠΈμ›¨μ΄λ₯Ό μ‚¬μš©ν•˜μ—¬ 200 μ½”λ“œκ°€ μžˆλŠ” λ‹€λ₯Έ ν•­λͺ©μ— λŒ€ν•΄ CORS 응닡을 μ˜¬λ°”λ₯΄κ²Œ κ΅¬μ„±ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

λ¬Έμ œκ°€ λ°œμƒν•˜λŠ” μ‚¬λžŒλ“€μ˜ 경우 κΈ°λ³Έ 4xxμ—μ„œ API κ²Œμ΄νŠΈμ›¨μ΄ 응닡을 μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
image

λ˜λŠ” serverless.ymlμ—μ„œ
yml GatewayDefault4XX: Type: 'AWS::ApiGateway::GatewayResponse' Properties: ResponseParameters: gatewayresponse.header.Access-Control-Allow-Origin: "'*'" gatewayresponse.header.Access-Control-Allow-Headers: "'*'" ResponseType: DEFAULT_4XX RestApiId: Ref: 'ApiGatewayRestApi'

λ‚˜λŠ” 같은 κ±Έλ¦ΌλŒμ— λΆ€λ”ͺ히고 있으며 였λ₯˜ λ©”μ‹œμ§€λ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•΄ λ‚΄ λ°˜μ‘ μ‘μš© ν”„λ‘œκ·Έλž¨μ— λ©”μ‹œμ§€λ₯Ό 전달할 수 μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. 이 λ¬Έμ œμ— λŒ€ν•œ μˆ˜μ • 사항이 진행 μ€‘μž…λ‹ˆκΉŒ?

@strass λŠ” 이 응닡 ν•„λ“œμ— λŒ€ν•΄ λͺ¨λ₯΄μ§€λ§Œ 였λ₯˜λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ λ„€νŠΈμ›Œν¬ 였λ₯˜λ₯Ό μΌ€ 수 μžˆμŠ΅λ‹ˆλ‹€.

export default onError(({ graphQLErrors, networkError }) => {
    if (graphQLErrors) {
        for (let { extensions: { code } } of graphQLErrors)
            handleTheError(code)
    }
    if (networkError) {
        switch (networkError.statusCode) {
            case 500:
                //
                break
            case 429:
                //
                break
            case undefined:
                //
                break
            default:
                console.error(networkError)
                break
        }
    }
})

빈 Observable을 λ°˜ν™˜ν•˜λŠ” @luki215 의 ν•΄κ²° 방법을 μ‹œλ„ν–ˆμ§€λ§Œ 제 κ²½μš°μ—λŠ” 이제 react-apolloκ°€ μ˜ˆμ™Έλ₯Ό throwν•˜κ²Œ λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€.

Uncaught (in promise) TypeError: Cannot read property 'data' of undefined
    at Mutation._this.onMutationCompleted (react-apollo.esm.js:627)
    at react-apollo.esm.js:564

Mutation λ₯Ό μ‚¬μš©ν•˜μ—¬ ꡬ성 μš”μ†Œμ— λ°˜ν™˜λœ 였λ₯˜λ₯Ό λ³€κ²½ν•˜κΈ° μœ„ν•΄ 이것을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

const errorLink = onError(({ forward, networkError, operation }) => {
  if (networkError) {
    const { message: errorMessage } = networkError.result;
    switch (networkError.statusCode) {
      case 400:
        if (errorMessage) {
          networkError.message = errorMessage;
        }
        break;
      case 403:
        window.location = '/users/login';
        break;
      default:
        break;
    }
  }
  forward(operation);
});

μ‚¬λžŒλ“€μ΄ μ—¬κΈ°μ„œ μ°Ύκ³  μžˆλŠ” 핡심은 networkError μ—μ„œ λ°˜ν™˜λœ 였λ₯˜ λ¬Έμžμ—΄μ„ μž¬μ •μ˜ν•˜λŠ” κΈ°λŠ₯이며 이 networkError.message = 'Some custom error message.' 둜 μ™„λ£Œλ©λ‹ˆλ‹€.

apollo-link-rest 및 이 νŒ¨ν‚€μ§€λ₯Ό νŒŒν—€μΉœ ν›„ ν•΄ν‚€ ν•΄κ²° 방법을 생각해 λƒˆμŠ΅λ‹ˆλ‹€. onError λ₯Ό μ‚¬μš©ν•˜λŠ” λŒ€μ‹  λ‚΄ μžμ‹ μ„ λ‹€μ‹œ μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€(μ•„λž˜).

μ˜λ„: NetworkError λ₯Ό κ°€λ‘œμ±„ μ‘°κ±΄λΆ€λ‘œ GraphQLError 둜 λ³€ν™˜ν•©λ‹ˆλ‹€. κ·Έ μ΄μœ λŠ” GraphQL κ·œμΉ™μ„ λ”°λ₯΄μ§€ μ•Šκ³  400 μƒνƒœ μ½”λ“œμ™€ ν•¨κ»˜ {"message": "{ \"key\": \"not valid\"}"} 와 같은 λͺ¨μ–‘을 λ°˜ν™˜ν•˜λŠ” REST 끝점을 μ‚¬μš©ν•˜κ³  있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 이것은 NetworkError둜 μ·¨κΈ‰λ˜μ–΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€.

μž‘λ™ 원리: 이 μ†”λ£¨μ…˜μ€ mutate promise catch λ‚΄μ—μ„œ 검색 및 ꡬ문 λΆ„μ„ν•˜κ³  ν•˜μœ„ μ–‘μ‹μ˜ μƒνƒœλ₯Ό μˆ˜μ •ν•  수 μžˆλŠ” λ°©μ‹μœΌλ‘œ μ‘λ‹΅μ—μ„œ μ‹€μ œ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό 체인 μ•„λž˜λ‘œ μ „λ‹¬ν•©λ‹ˆλ‹€. .

μž‘λ™ν•˜μ§€ μ•ŠλŠ” 것:

  • 였λ₯˜λ₯Ό μ˜¬λ°”λ₯Έ λ°©λ²•μœΌλ‘œ μ „λ‹¬ν•˜κΈ° μœ„ν•΄ observer.next({ data: { ... }, errors: { ... } }) λ₯Ό μ‚¬μš©ν•˜λŠ” 것을 μ„ ν˜Έν•˜μ§€λ§Œ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€(ν•΄λ‹Ή λ°μ΄ν„°λŠ” 아무데도 κ°€κ³  λŒμ—°λ³€μ΄ 약속은 ν•΄κ²°λ˜μ§€ μ•ŠλŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€).
  • observer.next() 및 observer.error() λ₯Ό μˆœμ„œλŒ€λ‘œ ν˜ΈμΆœν•˜λ©΄ μ˜ˆμƒν–ˆλ˜ λ™μž‘ 이 μ—†μŠ΅λ‹ˆλ‹€. 였λ₯˜ 호좜만 μ μš©λ˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.
const errorLink = new ApolloLink((operation, forward) => {
    return new Observable(observer => {
      let sub: ZenObservable.Subscription;

      try {
        sub = forward!(operation).subscribe({
          next: result => {
            console.log("A proper result looks like:", result);
            observer.next(result)
          },
          error: networkError => {
            try {
              const { message } = networkError.result;
              const error = new GraphQLError(message);
              const apolloError = new ApolloError({
                errorMessage: "Some error happened",
                graphQLErrors: [error],
                networkError: undefined,
              });

              observer.error(new Error(message));
            } catch (_) {
              observer.error(networkError)
            }
          },
          complete: () => {
            console.log("Calling complete()");
            observer.complete();
          },
        });
      } catch (e) {
        console.log("ErrorLink had an error of its own")
        observer.error(e);
      }

      return () => {
        if (sub) sub.unsubscribe();
      };
    });
  });

이것이 μž‘λ™ν•˜λŠ” κ²ƒμ²˜λŸΌ λ³΄μ΄μ§€λ§Œ mutate() ν•¨μˆ˜λŠ” ν•΄κ²°λ˜κ±°λ‚˜ κ±°λΆ€λ˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€ then() λ˜λŠ” catch() λͺ¨λ‘ ν˜ΈμΆœλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

const errorLink = new ApolloLink((operation, forward) => {
    return new Observable(observer => {
      let sub: ZenObservable.Subscription;

      try {
        sub = forward!(operation).subscribe({
          next: result => {
            console.log("A proper result looks like:", result);
            observer.next(result)
          },
          error: networkError => {
            try {
              const { message } = networkError.result;
              const error = new GraphQLError(message);

              // this is called, but it seems to be the end of the line
              console.log("Intercepting error, returning success");
              observer.next({ data: {}, errors: [ error ]});
            } catch (localError) {
              console.error("Error in link:", localError);
              observer.error(networkError)
            }
          },
          complete: () => {
            console.log("Calling complete()");
            observer.complete();
          },
        });
      } catch (e) {
        console.log("ErrorLink had an error of its own")
        observer.error(e);
      }

      return () => {
        if (sub) sub.unsubscribe();
      };
    });
  });

κ·Έλƒ₯ λ°€κ³ ...
μ§€κΈˆ 같은 였λ₯˜μ— κ±Έλ € λ„˜μ–΄μ‘ŒμŠ΅λ‹ˆλ‹€.
ꡬ성 μš”μ†Œ 자체의 였λ₯˜λ₯Ό μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ 응닡 ν•„λ“œμ˜ 였λ₯˜λ₯Ό μž¬μ„€μ •ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€...

μ–΄λ–€ 진전이 μžˆμŠ΅λ‹ˆκΉŒ?

같은 λ¬Έμ œμ— +1.

(적어도 λ‚΄ 였λ₯˜ μ „νŒŒ λ¬Έμ œμ— λŒ€ν•œ) 해결책을 μ°Ύμ•˜μ„ μˆ˜λ„ μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

errorLink μ—μ„œ map λ₯Ό forEach 둜 λ°”κΎΈλ©΄ 였λ₯˜κ°€ UI에 였λ₯˜λ₯Ό μ „νŒŒν•  수 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€(μ΄μ „μ—λŠ” UI ꡬ성 μš”μ†Œμ˜ result.errorκ°€ μ •μ˜λ˜μ§€ μ•Šμ•˜μœΌλ‚˜ μ΄μ œλŠ” 였λ₯˜κ°€ 있음).

const link = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors)
-    graphQLErrors.map(({ message, locations, path }) =>
+    graphQLErrors.forEach(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
      ),
    );

  if (networkError) console.log(`[Network error]: ${networkError}`);
});

λ‚˜λŠ” λ˜ν•œ 같은 λ¬Έμ œμ— μ§λ©΄ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λ₯Ό μœ„ν•œ ν•΄κ²° 방법은 빈 Observable을 λ°˜ν™˜ν•˜λŠ” κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ™Έλ₯Ό λ˜μ§€μ§€ μ•Šκ³  μ„œλ²„κ°€ 503에 μ‘λ‹΅ν•˜λŠ” 경우λ₯Ό λŒ€λΉ„ν•˜μ—¬ 쑰용히 μœ μ§€ νŽ˜μ΄μ§€λ‘œ λ¦¬λ””λ ‰μ…˜ν•˜κ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ° λ‚΄ μ½”λ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ•„λ§ˆλ„ λˆ„κ΅°κ°€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

import { Observable } from 'apollo-link';

...

onError(({ networkError }: any) => {
      if (networkError && networkError.status === 503) {
        this.redirectService.goToMaintenance();
        return Observable.of();
      }
});

...

이것은 μ €μ—κ²Œ νš¨κ³Όκ°€ μžˆμ—ˆμ§€λ§Œ λ¬Έμ„œμ—μ„œ λ§ν•˜λŠ” 것과 μ •ν™•νžˆ λ°˜λŒ€μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ "였λ₯˜ μ½œλ°±μ€ μš”μ²­μ„ λ‹€μ‹œ μ‹œλ„ν•˜λ €λŠ” 경우 forward(operation) ν˜ΈμΆœμ—μ„œ κ΄€μ°° κ°€λŠ₯ν•œ ν•­λͺ©μ„ μ„ νƒμ μœΌλ‘œ λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ 것을 λ°˜ν™˜ν•΄μ„œλŠ” μ•ˆ λ©λ‹ˆλ‹€."

였늘 Apolloλ₯Ό μ—…λ°μ΄νŠΈν•œ ν›„ μœ„μ˜ μ†”λ£¨μ…˜μ€ 더 이상 apollo-hooksλ₯Ό 톡해 UI에 λŒ€ν•œ graphQL 였λ₯˜λ₯Ό μ „λ‹¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λˆ„κ΅¬λ“ μ§€ λ‹€λ₯Έ 해결책이 μžˆμŠ΅λ‹ˆκΉŒ?

@strass μœ„μ˜ μ†”λ£¨μ…˜ 이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 이유λ₯Ό μ„€λͺ…ν•  수 μžˆμŠ΅λ‹ˆλ‹€. IMO 그듀은 forEach 및 map λ₯Ό μ‚¬μš©ν•˜μ—¬ μ •ν™•νžˆ λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

더 이상 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€(https://github.com/apollographql/apollo-link/issues/855#issuecomment-538010335 μ°Έμ‘°).

이에 λŒ€ν•œ 진전이 μžˆμŠ΅λ‹ˆκΉŒ?

응닡 객체λ₯Ό μ „ν˜€ 얻을 수 μ—†λ‹€λ©΄ μ„œλ²„κ°€ μž¬μΈμ¦μ„ μœ„ν•΄ "Location" 헀더가 μžˆλŠ” 302λ₯Ό λ°˜ν™˜ν•˜λŠ” 경우λ₯Ό μ–΄λ–»κ²Œ μ²˜λ¦¬ν•΄μ•Ό ν• κΉŒμš”?

λˆ„κ΅°κ°€ λ‹¨μ„œκ°€ 있으면 μ•Œλ €μ£Όμ‹­μ‹œμ˜€. μ™œλƒν•˜λ©΄ μš°λ¦¬λŠ” μ•„ν΄λ‘œλ₯Ό 포기할 생각을 ν•˜κ³  있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

이것은 https://github.com/apollographql/apollo-link/issues/297#issuecomment -350488527에 큰 도움이 λ˜μ—ˆμœΌλ©° λ„€νŠΈμ›Œν¬ 응닡을 읽을 수 있게 ν•΄μ€λ‹ˆλ‹€.

인증 계측/κ²Œμ΄νŠΈμ›¨μ΄ APIμ—μ„œ 무단 응닡이 λ°˜ν™˜λ  λ•Œ μ€‘μš”ν•œ κ²ƒμž…λ‹ˆλ‹€.

이것을 핡심 κΈ°λŠ₯의 μΌλΆ€λ‘œ 보고 μ‹ΆμŠ΅λ‹ˆλ‹€!

이에 λŒ€ν•œ 진전이 μžˆμŠ΅λ‹ˆκΉŒ? 이것은 μ˜λ„λœ λ™μž‘μž…λ‹ˆλ‹€. 200이 μ•„λ‹Œ μƒνƒœ μ½”λ“œλ‘œ GraphQL 였λ₯˜λ₯Ό ν΄λΌμ΄μ–ΈνŠΈμ— 전달할 수 μžˆλŠ” λ‹€λ₯Έ 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

λ„€νŠΈμ›Œν¬ 였λ₯˜λ₯Ό ν¬μ°©ν•˜κ³  μˆ˜μ •ν•˜λŠ” 데 λ¬Έμ œκ°€ μžˆλŠ” λ‹€λ₯Έ μ‚¬λžŒμ„ μœ„ν•œ μ°Έκ³  μ‚¬ν•­μž…λ‹ˆλ‹€. λ‚˜λŠ” graphql의 λ‚΄λΆ€ 였λ₯˜λ‘œ λ„€νŠΈμ›Œν¬ 였λ₯˜λ₯Ό ν’€λ €κ³  μ‹œλ„ν–ˆκ³  λ‹€μŒκ³Ό 같이 λλ‚¬μŠ΅λ‹ˆλ‹€.

const errorHandler = onError(({ graphQLErrors, networkError, operation, forward, response }) => {
    if (graphQLErrors) {
      console.error('apollo errors', graphQLErrors);
    }
    if (networkError) {
      console.error('apollo network errors', networkError);
      if (!!networkError['error'] && !!networkError['error']['errors'] && networkError['error']['errors'][0]) {
        console.error('unwrapping apollo network errors');
        networkError.message = networkError['error']['errors'][0].message;
        // you may also be able to set networkError.message to null based on criteria to remove the error, even if you can't prevent an error from being triggered altogether
      }
    }
  }
);

// Create an http link:
const httpLink = new HttpLink(this.httpClient).create({
  uri: this.uri,
  headers: new HttpHeaders({
    Authorization: this.token
  }),
  includeExtensions: true
});

const httpErrorLink = ApolloLink.from([
  errorHandler,
  httpLink,
]);

기본적으둜 일반 λ„€νŠΈμ›Œν¬ 였λ₯˜ λ©”μ‹œμ§€μΈ λ©”μ‹œμ§€λ₯Ό 첫 번째 λ‚΄λΆ€ 였λ₯˜ λ©”μ‹œμ§€λ‘œ λ°”κΏ‰λ‹ˆλ‹€. λ‚˜μ²˜λŸΌ μ—¬κΈ°κΉŒμ§€ 온 μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 수 μžˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰