Apollo-link-rest: Menangani respons kesalahan

Dibuat pada 2 Okt 2018  ·  16Komentar  ·  Sumber: apollographql/apollo-link-rest

Halo, saya memiliki API Masuk ini yang akan menerima isi permintaan sebagai:

{
    "authentications": {
        "emailAddress": "[email protected]",
        "password": "11111111"
    }
}

Token pengembalian server jika berhasil:

{
    "authentications": {
        "token": "eyJhbGoiU3RvcmUifV0sImNyZWF0ZWRBdCI6IjIwMTgtMDktMTZUMTg6NTA6NTYuNT"
    }
}

Jika masukan email atau kata sandi salah, itu akan mengembalikan:

{
    "message": "Cannot find document for class 'User'. searched with parameters: '{\"emailAddress\":\"[email protected]\"}'",
    "errorCode": 1103,
    "status": 404
}

Saya berhasil masuk dengan skema GraphQL seperti ini:

gql`
  fragment Authentications on any {
    emailAddress: String
    password: String
  }

  fragment AuthInput on REST {
    authentications {
      Authentications
    }
  }

  mutation signIn($input: AuthInput!) {
    authPayload(input: $input) 
      @rest(type: "AuthPayload", path: "/api/v1/authentications", endpoint:"UsersService", method:"POST") {
      authentications @type(name:"Auth"){
        token
      }
    }
  }
`;

Pertanyaan saya adalah bagaimana saya bisa mendapatkan respon jika terjadi kesalahan (email / password salah)? Karena saat ini jika server mengembalikan kesalahan, responsnya selalu nol:

Object {
    "data": Object {
        "authPayload": null,
    },
    "errors": undefined,
}
help wanted 🛠 question❔

Komentar yang paling membantu

Saya juga terjebak dalam masalah ini. Apakah ada alasan untuk tidak mengembalikan respons 404 penuh alih-alih nol?

Semua 16 komentar

Jika Anda tidak dapat menemukan kesalahan 400+, saya pikir masalah ini akan berguna.
https://github.com/apollographql/apollo-link-rest/issues/151

FYI: untuk kredensial yang salah, Anda harus mengembalikan 401.
https://stackoverflow.com/questions/1959947/whats-an-appatible-http-status-code-to-return-by-a-rest-api-service-for-a-val

Halo semua,

Saya baru saja mengalami ini dan saya juga bertanya-tanya apa cara yang disarankan untuk menangani 404. Ini tidak memicu apollo-link-error misalnya.

Sejauh ini saya berpikir untuk menulis tautan penanganan kesalahan khusus, atau memeriksa konten data dalam respons di setiap komponen <Query /> .

FWIW Saya memiliki kasus yang sama di mana server mengembalikan 404, bukan 401 misalnya, tetapi sayangnya mengubah server bukanlah pilihan pada saat ini.

Saya pikir akan bermanfaat untuk menangani kasus penggunaan ini karena kode status untuk REST sangat berbeda - dan lebih bervariasi dan penting - daripada yang dari GraphQL.

Saya juga terjebak dalam masalah ini. Apakah ada alasan untuk tidak mengembalikan respons 404 penuh alih-alih nol?

Saya belum pernah mengalami kasus di mana tidak memperlakukan 404 sebagai kesalahan telah membantu saya, saya terus berusaha menemukan cara yang baik untuk mengatasi fakta itu.

Apakah pemikiran bahwa 404 Not found dapat mendeskripsikan kueri data yang berhasil, dengan benar menghasilkan himpunan kosong?

Ini juga bisa menandakan bahwa pemilik layanan membuat perubahan yang sangat mengganggu sehingga titik akhir yang sebelumnya tersedia telah menghilang.

Saya pikir kasus pertama lebih baik ditangani oleh 200 OK bersama dengan entitas aplikasi kosong atau nol. Setidaknya, sepertinya kedua kasus ini harus dapat dilihat oleh klien, karena keduanya sangat berbeda.

Ya, kumpulan data yang sengaja kosong sedikit lebih umum daripada yang orang kira? (Setidaknya saya terkejut!) Karena pengguna sering mengumpulkan beberapa jaringan & panggilan lainnya ke dalam satu panggilan meta, secara default memberikan kesalahan pada 404 memiliki dampak yang sangat besar, karena satu 404 akan menghentikan semua pengambilan data lain yang terjadi secara paralel. Saya setuju jika hanya ada satu panggilan REST per kueri GraphQL yang dieksekusi, menurut saya kita harus melakukan kesalahan mengingat semantik REST resmi.

Dalam praktiknya, tidak melempar kesalahan secara default sepertinya lebih baik! Karena Anda dapat menyiasatinya dengan menambahkan pengambilan khusus, dan ini terasa seperti "bersikap liberal dalam apa yang Anda terima"; pilihan ini terasa cocok dengan salah satu tujuan utama Apollo-link-rest: membantu pengguna yang tidak perlu mengontrol backend, dan hanya ada banyak server "sebagian besar-REST" di luar sana, jadi pelanggaran semantik sering terjadi .

@williamboman relatif mudah untuk mengonfigurasi Apollo-link-rest agar menggunakan 404 jika Anda menggunakan Parameter customFetch Saya tidak berada di komputer saya, tetapi beri tahu saya jika Anda memerlukan bantuan untuk melakukannya!

Hai @fbartho Bisakah Anda membantu saya menulis customFetch untuk menangani kesalahan 404? Apakah ada contohnya?

@nasnain :

Dalam javascript akan terlihat seperti ini:

export async function customFetch(requestInfo, init) {
  const response = await fetch(requestInfo, init);
  if (response.status === 404) {
    throw new Error("404 File Not Found"); // Customize this however you like!
  }
  return response;
}

(Dalam TypeScript, ini akan menjadi sedikit lebih bertele-tele)

@fbartho Terima kasih atas tanggapan yang cepat. Saya bisa menangkap 404 sekarang.
Tetapi bagaimana saya memastikan networkError dari apollo-link-error menangkap kesalahan (membuang Error baru ("404 File Not Found")) yang tertulis di dalam custom fetch?

Ah, sayangnya, saya pikir itu akan muncul melekat pada array graphQLErrors (bukan pada properti networkError ) karena aturan internal ApolloClient (tentang cara kerja tautan).

Mungkin saja ini bisa diperbaiki, tapi saya tidak tahu caranya. - HTTPLink harus tahu bagaimana melakukannya, dan saya belum sempat menyelidikinya. Kami memiliki metode pembantu dalam basis kode (pekerjaan) kami yang hanya membongkar kesalahan bersarang. (Ini juga diperlukan untuk kesalahan yang dilempar dari apollo-link-state untuk kami jadi itu bukan prioritas)

@fbartho Saya tidak mendapatkan kesalahan sama sekali dalam kasus ini. data mengembalikan null. mengharapkan kesalahan alih-alih data jika kita melontarkan kesalahan. Tidak yakin bagaimana menerapkan ini.

@anasnain Sudah lama sekali saya tidak mengaturnya, saya lupa.

Anda juga perlu mengonfigurasi instance apollo-link-error, ini konfigurasi saya:

const attachGQLErrorsToNetworkError = (
    graphQLErrors: readonly GraphQLError[],
    networkError: Error,
): void => {
    (networkError as any).tr_graphQLErrors = graphQLErrors;
    return;
};

/** Set behavior when errors occur and handle our own TR errors */
export const apolloErrorLink = onError((errorResponse: ErrorResponse) => {
    const {
        graphQLErrors = [],
        networkError,
    }: {
        graphQLErrors?: readonly GraphQLError[];
        networkError?: Error;
    } = errorResponse;

    /**
     * Our error parsing (function recursiveGQLErrorsFromNetworkError) rely
     * on attaching the following graphql errors.
     * Let's make sure to not attach anything `wrong` (ie: null, empty, ...)
     */
    const hasGraphQLErrors: boolean =
        graphQLErrors != null &&
        Array.isArray(graphQLErrors) &&
        graphQLErrors.length > 0;

    if (networkError && hasGraphQLErrors) {
        /*
         * graphQLErrors are not being passed through the chain of links,
         * but network errors are attaching the graphQLErrors to networkError
         * to be able to access them in a component
         */
        attachGQLErrorsToNetworkError(graphQLErrors, networkError);
    }
});

Setelah perenungan lebih lanjut: Saya tidak sepenuhnya yakin saya memahami situasi yang Anda gambarkan.

Apakah masalah Anda tidak dapat membaca "kesalahan 404" di kode komponen / reaksi?

@bayu_joo
Skenario: Saya menjalankan di bawah rest APIquery dan harapannya adalah saya harus mendapatkan objek kesalahan jika mengembalikan kode kesalahan 404 seperti dalam kasus kesalahan 4xx lainnya dan kesalahan 5xx. tetapi dalam kasus ini, kesalahannya tidak terdefinisi dan datanya nol.
const {memuat, kesalahan, data} = useQuery (CLIENT_API_QUERY);

Ini adalah contoh klien Apollo:

async function customFetch(requestInfo, init) {
    const response = await fetch(requestInfo, init);
    if (response.status === 404) {
        response.json().then((errorResponse) => {
          throw new Error(errorResponse);
        });
    }
    return response;
  }

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

const restLink = new RestLink({
    uri: 'https://run.mocky.io/v3/df72bacd-39cb-476d-bfda-06d7f5e9d77d',
    customFetch: (requestInfo, init) => customFetch(requestInfo, init)
});

const apolloClient = new ApolloClient({
    link: ApolloLink.from([errorLink, restLink]),
    new InMemoryCache(),
  });
export default apolloClient;

@anasnain - satu hal yang saya sadari adalah menurut saya Anda tidak dapat memberikan objek sewenang-wenang saat melakukan new Error

Juga, saya pikir Anda melewatkan menunggu, jadi pernyataan throw terjadi di luar panggilan customFetch restLink!

const err = new Error("404 Error");
try {
  err.responseJson = await response.json(); // This await crucial to get the error in the right spot!
} catch (parsingError) {
  // figure out what you want to do with parsingError?
}
throw err;
Apakah halaman ini membantu?
0 / 5 - 0 peringkat