<p>apollo-link-error mengembalikan kesalahan ke pemanggil</p>

Dibuat pada 15 Apr 2019  ·  17Komentar  ·  Sumber: apollographql/apollo-link

Jadi saya menggunakan Apollo-link-error untuk mengelola kesalahan global auth dan admin. Tetapi jika saya menggunakannya, metode tangkapan saya di janji saya tidak mengembalikan kesalahan.

Sepertinya semua kesalahan melalui apollo-link-error dan tidak diteruskan kembali ke metode pemanggil.

Apakah ada cara untuk mengembalikan kesalahan ke penelepon sehingga saya dapat mengelola beberapa kesalahan secara lokal dan beberapa kesalahan secara global?

Komentar yang paling membantu

Saya menemukan solusinya, agak aneh, tetapi itu adalah:

Ini hanya mencetak pesan

  updateProfile: function() {
      this.$apollo
        .mutate({
          mutation: UPDATE_PROFILE,
          variables: current_user
        })
        .catch((error) => {
          console.log("this prints just the message", error);
        });
    }

TAPI ini mencetak konten penuh kesalahan

  updateProfile: function() {
      this.$apollo
        .mutate({
          mutation: UPDATE_PROFILE,
          variables: current_user
        })
        .catch(({ graphQLErrors }) => {
          console.log("this prints the full content of 'errors'", graphQLErrors);
        });
    }

Saya pikir masalah ini bisa ditutup
@Nosherwan @romucci @Sceat @lbrdar

Semua 17 komentar

Saya memiliki masalah yang sama di aplikasi saya. Saya ingin menangkap semua kesalahan dalam tautan kesalahan (misalnya agar saya dapat mencatatnya) tetapi saya juga ingin meneruskannya ke penelepon asli dan menanganinya di sana karena mungkin berisi pesan kesalahan khusus yang perlu ditampilkan kepada pengguna .

kode saya:

  • di penyedia:
const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(({ message, locations, path }) => {
        console.log(`[GraphQL error]: ${message}, Location: ${locations}, Path: ${path}`);
      },
    );
  }
});

const client = new ApolloClient({
  link: authLink.concat(errorLink).concat(httpLink),
  cache: new InMemoryCache(),
});

  • dalam komponen:
 loginMutation({ variables: { data } })
    .then(({ data, errors }) => {
      if (errors) {
        // I WANT TO BE ABLE TO READ ERROR MESSAGE HERE SO I CAN DISPLAY IT TO THE USER
      } else if (data) {
        ....
      }
    });

Perhatikan bahwa memanggil forward tidak akan membantu karena mengembalikan undefined sebagai argumen ke then jadi saya tidak akan memiliki atau data atau kesalahan dan menyetel errors ke null juga bukan opsi n karena saya sebenarnya perlu membaca kesalahan.

@lbrdar Sudahkah Anda menemukan solusi untuk ini?

Tidak

@lbrdar Bukankah cara untuk melakukan ini adalah dengan catch ?

 loginMutation({ variables: { data } })
    .then(({ data, errors }) => {
      if (errors) {
        // I WANT TO BE ABLE TO READ ERROR MESSAGE HERE SO I CAN DISPLAY IT TO THE USER
      } else if (data) {
        ....
      }
    }).catch(errors => {

    });

@lbrdar @romucci Saya menghadapi masalah yang sama. Apakah kalian akhirnya menyelesaikan ini?

@Nosherwan Saya baru saja menginstal versi 1.1.11 dan semuanya berfungsi dengan baik sekarang... Anda juga dapat memeriksa janji batin Anda (mungkin di suatu tempat Anda lupa mengembalikan janji di dalam janji lain)

@merksam terima kasih atas komentarnya.
Saya menggunakan versi yang sama persis dengan Anda. Sayangnya perilakunya sama.

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

Dalam blok kode di atas, graphQLErrors ditangkap dan sesuatu dapat dilakukan di handler onError. Namun kesalahan tersebut tidak diteruskan ke janji panggilan yang sebenarnya.
Saya menggunakan fungsi async jadi alih-alih 'lalu' saya menggunakan kata kunci menunggu, dan itu ada di dalam blok coba tangkap.
blok catch menangkap kesalahan, tetapi tidak ada kesalahan yang diteruskan ke sana.

Apakah seseorang menemukan solusi untuk ini?

@Nosherwan @prem-prakash Bisakah kami menghubungi suatu tempat dalam obrolan atau bahkan membuat panggilan jadi kami mencoba mencari tahu mengapa itu berhasil dalam kasus saya dan tidak di kasus Anda? (jika masih relevan)

Saya menemukan solusinya, agak aneh, tetapi itu adalah:

Ini hanya mencetak pesan

  updateProfile: function() {
      this.$apollo
        .mutate({
          mutation: UPDATE_PROFILE,
          variables: current_user
        })
        .catch((error) => {
          console.log("this prints just the message", error);
        });
    }

TAPI ini mencetak konten penuh kesalahan

  updateProfile: function() {
      this.$apollo
        .mutate({
          mutation: UPDATE_PROFILE,
          variables: current_user
        })
        .catch(({ graphQLErrors }) => {
          console.log("this prints the full content of 'errors'", graphQLErrors);
        });
    }

Saya pikir masalah ini bisa ditutup
@Nosherwan @romucci @Sceat @lbrdar

bagaimana dengan menambahkan ini ke dokumentasi?

Maaf, tetapi solusi di atas tidak berhasil. Saya kira contoh lengkap tentang cara mengirim kembali graphqlErrors dalam kesalahan tautan kembali ke pemanggil awal.

Dalam kasus saya, ketika ada kesalahan, objek ApolloQueryResult berikut tidak mendapatkan detail kesalahan yang dihibur di onError. Beberapa di coba ... menangkap sekitar panggilan. Tidak bisa mendapatkan detail graphqlError dari server. Hanya "kesalahan 400"..

const gqlResult: ApolloQueryResult<IGReturnData<
            IAllDataTypes
        >> = await apolloClient.query<IGReturnData<IAllDataTypes>, TVariables>({
            query: queryGql,
            variables: queryVariables,
            errorPolicy: "all",
        });

konfigurasi server:

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

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

const httplink = new HttpLink({
    uri: "/graphql",
    credentials: "include",
});

const links = [errorLink, httplink];

export const apolloClient = new ApolloClient({
    link: ApolloLink.from(links),
    cache: new InMemoryCache({ addTypename: false, fragmentMatcher }),
});

@prem-prakash terima kasih.... penyelamat..

Masalah ini sangat persisten. Saya tidak memiliki kendali atas server graphql pada proyek saya, hanya klien. Server merespons dengan kesalahan graphql dalam bentuk yang benar, tetapi dengan kode status 400. Di tautan kesalahan saya memiliki akses ke graphQLErrors , tetapi dalam mutasi komponen, ketika saya mengeluarkan graphQLErrors seperti yang disarankan oleh @prem-prakash, graphQLErrors adalah array kosong . Saya hanya dapat mengakses pesan default "Kesalahan: Kesalahan jaringan: Respons tidak berhasil: Kode status diterima 400". Apollo menggagalkan pesan kesalahan yang dapat dibaca manusia dari server ("pengguna atau kata sandi salah") karena kode status 400 adalah titik lengkap untuk Apollo.

Apakah ada orang di luar sana yang berhasil menangani respons kode status 400 dengan pesan kesalahan, dan meneruskan pesan itu ke UI di komponen yang disebut mutasi?

Oke, saya memiliki pendekatan yang cukup tidak masuk akal, tetapi berhasil:

Saya menyetel boolean hasGraphError dalam cache, dan juga menyimpan pesan kesalahan dalam cache.

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(error => {
      // log gql error(s)
      console.log("[GraphQL error]: ", error);
      // cache error
      client.writeData({
        data: {
          hasGraphError: true,
          currentGraphError: error.message
        }
      });
    });
  }
  if (networkError) {
    // log network errors
    console.log("[Network error]: ", networkError);
  }
});

Kemudian dalam komponen MutationError, saya menanyakan cache untuk keberadaan kesalahan dan pesan kesalahan, secara kondisional membuat kesalahan gql atau kesalahan jaringan nyata:

const HAS_ERROR = gql`
  query IsGraphErrorPresent {
    hasGraphError <strong i="11">@client</strong>
    currentGraphError <strong i="12">@client</strong>
  }
`;
export default function MutationError({ error }) {
  const { data } = useQuery(HAS_ERROR);
  const defaultErrorMessage =
    "We're having trouble connecting. Please check your internet connection and try again.";

  // real network error
  if (error && error.message.includes("Failed to fetch")) {
    return <Error>{defaultErrorMessage}</Error>;
  }

  // graph error
  if (error && data && data.hasGraphError) {
    return <Error>{data.currentGraphError}</Error>;
  }

  // probably a real server/network error
  if (error) {
    return <Error>{defaultErrorMessage}</Error>;
  }

  return null;
}

Ini akan menjadi global karena saya membutuhkannya pada semua mutasi karena server saya _always_ mengembalikan 400 untuk apa yang seharusnya menjadi 200 + kesalahan graphql (saya sedikit asin tentang itu)...

Jadi yang penting di sini, adalah bahwa pada setiap mutasi komponen, saya menggunakan panggilan balik onError kosong yang mencegah pengecualian yang tidak tertangani dari Apollo, dan jika berhasil saya harus ingat untuk mengatur ulang boolean hasGraphError di cache:

  const [someMutation, { loading, error, client }] = useMutation(SOME_MUTATION, {
    onError() {
      // this callback prevents apollo from throwing
      // ...unhandled exception on 400 status code
    },
    onCompleted({ someMutation }) {
      client.writeData({
        data: {
          hasGraphError: false
        }
      });
    }
  });

Kemudian komponen kesalahan mutasi mengambil kesalahan useMutation sebagai props (yang keduanya memungkinkan kesalahan jaringan nyata untuk ditentukan, dan memastikan bahwa kita tidak merender kesalahan gql cache global pada komponen yang salah):

  {loading && <Spinner />}
  {error && <MutationError error={error} />}

Seperti yang saya katakan, pendekatan ini cukup tidak masuk akal, namun saat ini sedang bekerja untuk memecahkan:

  1. umumnya dapat menangani kesalahan graphql di UI bahkan jika responsnya memiliki kode status non-200
  2. secara khusus dapat meneruskan kesalahan dari konfigurasi kesalahan tautan-apollo ke komponen pemanggil, untuk dirender di UI

Masalah dengan pendekatan ini sebagai kode: ini hanya menulis kesalahan GQL terakhir dalam larik ke cache, sehingga tidak mendukung beberapa kesalahan GQL secara bersamaan. Ini seharusnya cukup mudah untuk dikelola, dengan membangun array kesalahan, dan menyimpannya di cache, tetapi Anda harus mendefinisikan skema/resolver lokal untuk melakukan ini, atau berpotensi hanya JSON.stringify untuk disimpan di cache sebagai string. Anda juga harus menghapus currentGraphError dalam cache jika berhasil, daripada hanya menyetel boolean ke false.

Semoga itu membantu seseorang!

Juga, jika ini membantu, perhatikan bahwa errorPolicy saat ini tidak berfungsi pada kait useMutation, ini adalah bug, dan baru-baru ini dibahas dalam PR ini: https://github.com/apollographql/apollo-client/pull/5863 , tetapi belum berhasil dirilis saat ini.

Adakah kemajuan dalam hal ini dari para pengembang?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

valerybugakov picture valerybugakov  ·  5Komentar

ignivalancy picture ignivalancy  ·  5Komentar

NicholasLYang picture NicholasLYang  ·  4Komentar

Nickersoft picture Nickersoft  ·  3Komentar

ChenRoth picture ChenRoth  ·  4Komentar