Apollo-link-rest: معالجة الاستجابة للخطأ

تم إنشاؤها على ٢ أكتوبر ٢٠١٨  ·  16تعليقات  ·  مصدر: apollographql/apollo-link-rest

مرحبًا ، لدي واجهة برمجة تطبيقات تسجيل الدخول هذه والتي ستأخذ نص الطلب على النحو التالي:

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

سيرجع الخادم الرمز المميز في حالة النجاح:

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

في حالة عدم صحة إدخال البريد الإلكتروني أو كلمة المرور ، سيتم إرجاع:

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

يمكنني تسجيل الدخول بنجاح باستخدام مخطط GraphQL مثل هذا:

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
      }
    }
  }
`;

سؤالي هو كيف يمكنني الحصول على الرد في حالة وجود خطأ (بريد إلكتروني / كلمة مرور خاطئة)؟ لأنه في الوقت الحالي إذا أعاد الخادم الخطأ ، تكون الاستجابة فارغة دائمًا:

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

التعليق الأكثر فائدة

أنا أيضًا عالق في هذه المشكلة. هل هناك سبب لعدم إرجاع استجابة 404 كاملة بدلاً من فارغة؟

ال 16 كومينتر

إذا لم تتمكن من اكتشاف الخطأ 400+ ، أعتقد أن هذه المشكلة ستكون مفيدة.
https://github.com/apollographql/apollo-link-rest/issues/151

لمعلوماتك: للحصول على بيانات اعتماد خاطئة ، يجب عليك إرجاع 401.
https://stackoverflow.com/questions/1959947/whats-an- appropriate-http-status-code-to-return-by-a-rest-api-service-for-a-val

أهلا بكم،

لقد واجهت هذا للتو وأنا أيضًا أتساءل ما هي الطريقة الموصى بها للتعامل مع 404. لا يؤدي إلى تشغيل apollo-link-error على سبيل المثال.

حتى الآن أفكر في كتابة ارتباط معالج خطأ مخصص ، أو التحقق من محتوى البيانات في الاستجابة في كل مكون <Query /> .

FWIW لدي نفس الحالة حيث يقوم الخادم بإرجاع 404 بدلاً من 401 على سبيل المثال ، ولكن تغيير الخادم للأسف ليس خيارًا في هذه المرحلة.

أعتقد أنه سيكون من المفيد معالجة حالة الاستخدام هذه لأن رموز الحالة الخاصة بـ REST مختلفة جدًا - وأكثر تنوعًا وأهمية - عن تلك الموجودة في GraphQL.

أنا أيضًا عالق في هذه المشكلة. هل هناك سبب لعدم إرجاع استجابة 404 كاملة بدلاً من فارغة؟

لم أجد بعد في حالة ساعدني فيها عدم التعامل مع 404 كخطأ ، وما زلت أحاول إيجاد طريقة لطيفة للتغلب على هذه الحقيقة.

هل التفكير في أن 404 غير موجود يمكنه وصف استعلام بيانات ينتج المجموعة الفارغة بنجاح وبشكل صحيح؟

قد يشير أيضًا إلى أن مالكي الخدمة قاموا بإجراء تغيير فاصل بحيث اختفت نقطة النهاية المتوفرة مسبقًا.

أعتقد أنه يمكن التعامل مع الحالة الأولى بشكل أفضل بواسطة 200 موافق مع كيان تطبيق فارغ أو فارغ. على الأقل ، يبدو أنه يجب على العميل تمييز هاتين الحالتين بسهولة ، لأنهما مختلفتان تمامًا.

نعم ، مجموعات البيانات الفارغة عمدًا أكثر شيوعًا مما قد يعتقده المرء؟ (على الأقل لقد فوجئت!) نظرًا لأن المستخدمين غالبًا ما يجمعون مكالمات متعددة للشبكات ومكالمات أخرى في مكالمة وصفية واحدة ، فإن التخلف عن الخطأ في الخطأ 404 له تأثير كبير ، لأن 404 واحد سينهي جميع عمليات جلب البيانات الأخرى التي تحدث بالتوازي. أوافق على أنه إذا تم تنفيذ استدعاء REST واحد فقط لكل استعلام GraphQL ، فقد بدا لي أننا يجب أن نخطئ بالنظر إلى دلالات REST الرسمية.

من الناحية العملية ، يبدو أن عدم إلقاء خطأ بشكل افتراضي أفضل! نظرًا لأنه يمكنك التغلب على هذا عن طريق إضافة جلب مخصص ، وهذا يبدو وكأنه "كن ليبراليًا فيما تقبله" ؛ يبدو أن هذا الاختيار يتطابق مع أحد الأغراض الرئيسية لـ Apollo-link-rest: مساعدة المستخدمين الذين لا يتحكمون بالضرورة في الواجهة الخلفية ، وهناك العديد من الخوادم "معظمها REST" هناك ، لذا فإن الانتهاكات الدلالية شائعة .

williamboman من customFetch المعلمة لست على جهاز الكمبيوتر الخاص بي ، ولكن أخبرني إذا كنت بحاجة إلى مساعدة في القيام بذلك!

مرحبًا fbartho هل يمكنك مساعدتي في كتابة customFetch لمعالجة أخطاء 404؟ هل هناك بعض الأمثلة على ذلك؟

anasnain :

سيبدو في جافا سكريبت مثل هذا:

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;
}

(في TypeScript سيكون أكثر تفصيلاً)

fbartho شكرا على الاستجابة السريعة. أنا قادر على التقاط 404 الآن.
ولكن كيف يمكنني التأكد من أن خطأ NetworkError في apollo-link-error يكتشف الخطأ (خطأ جديد ("404 File Not Found")) مكتوب داخل جلب مخصص؟

آه ، لسوء الحظ ، أعتقد أنه سيظهر مرفقًا بمصفوفة graphQLErrors (وليس على خاصية networkError ) بسبب قواعد ApolloClient الداخلية (حول كيفية عمل الروابط).

من الممكن أن يكون هذا قابلًا للإصلاح ، لكنني لا أعرف كيف. - يجب أن يعرف HTTPLink كيفية القيام بذلك ، ولم تتح لي الفرصة للتحقيق. لدينا طريقة مساعدة في قاعدة التعليمات البرمجية (العمل) الخاصة بنا والتي تقوم فقط بفك ضغط الأخطاء المتداخلة. (كان هذا ضروريًا أيضًا للأخطاء التي تم إلقاؤها من apollo-link-state بالنسبة لنا ، لذا لم تكن أولوية بالفعل)

fbartho لا أحصل على أي خطأ على الإطلاق في هذه الحالة. يتم إرجاع البيانات فارغة. كنا نتوقع خطأً بدلاً من البيانات إذا كنا نرتكب خطأً. لست متأكدا من كيفية تنفيذ هذا.

anasnain لقد مر وقت طويل منذ أن قمت

تحتاج أيضًا إلى تكوين مثيل خطأ apollo-link ، هذا هو التكوين الخاص بي:

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);
    }
});

بعد مزيد من التفكير: لست متأكدًا تمامًا من أنني أفهم الموقف الذي تصفه.

هل المشكلة هي أنه لا يمكنك قراءة "خطأ 404" في كود المكون / رد الفعل؟

تضمين التغريدة
السيناريو: أعمل أسفل استعلام API الباقي والتوقع هو أنني يجب أن أحصل على كائن خطأ في حالة إرجاع رمز الخطأ 404 تمامًا كما هو الحال في حالة أخطاء 4xx الأخرى وأخطاء 5xx. ولكن في هذه الحالة ، الخطأ غير محدد والبيانات فارغة.
const {loading، error، data} = useQuery (CLIENT_API_QUERY) ؛

هذا هو مثيل عميل 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 - هناك شيء واحد new Error

أيضًا ، أعتقد أنك فاتتك فترة انتظار ، لذا فإن كشف حساب throw يحدث خارج استدعاء restLink customFetch!

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;
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات