Xử lý lỗi với hook sử dụng Reac-apollo


10

Tôi đã cố gắng giải quyết vấn đề này nhưng không tìm thấy câu trả lời mạnh mẽ cho vấn đề này. Tôi đang cố gắng thực hiện một đột biến đăng nhập bằng cách sử dụng hook useMuting.

TLDR; Tôi muốn biết chính xác sự khác biệt giữa onError được truyền trong các tùy chọn và lỗi được đưa ra cho tôi bởi useMuting

Đây là đoạn mã của tôi

const [login, { data, loading, error }] = useMutation(LOGIN_QUERY, {
        variables: {
            email,
            password
        },
        onError(err) {
            console.log(err);
        },
});

Về phía máy chủ, tôi có một email cài sẵn / mã hóa cứng được sử dụng để đăng nhập và tôi không sử dụng Apollo hoặc bất kỳ ứng dụng khách nào khác. Trong trình giải quyết Đột biến đăng nhập này, tôi chỉ cần đưa ra lỗi nếu email không giống nhau bằng cách sử dụng

throw new Error('Invalid Email');

Bây giờ tôi muốn xử lý lỗi này ở phía máy khách (React). Nhưng mối quan tâm của tôi là nếu tôi sử dụng 'lỗi' được trả về từ hook useMuting và cố gắng hiển thị lỗi theo cách này

render() {
...
{error && <div> Error occured </div>}
...
}

lỗi được cập nhật trong giao diện người dùng nhưng ngay lập tức React hiển thị cho tôi một màn hình với Từ chối không xử lý (Lỗi): Lỗi biểu đồ: Lỗi thông báo lỗi tùy chỉnh của tôi

Nhưng, nếu tôi sử dụng onError trong các tùy chọn để sử dụng chức năngMutate, thì nó sẽ không hiển thị cho tôi màn hình này và tôi có thể làm bất cứ điều gì tôi muốn với lỗi.

Tôi muốn biết chính xác sự khác biệt giữa onError được truyền trong các tùy chọn và lỗi được đưa ra cho tôi bởi useMuting và tại sao React cho tôi thấy màn hình lỗi đó khi onError không được sử dụng.

Cảm ơn!

Câu trả lời:


32

Apollo cho thấy hai loại lỗi thông qua API của nó: lỗi GraphQL , mà được trả về như là một phần của câu trả lời là errors, bên cạnh data, và lỗi mạng xảy ra khi một yêu cầu không. Lỗi mạng sẽ xảy ra khi không thể truy cập máy chủ hoặc nếu trạng thái phản hồi là bất kỳ thứ gì khác ngoài 200 - truy vấn có errorstrong phản hồi vẫn có thể có trạng thái 200. Ví dụ: truy vấn không hợp lệ sẽ dẫn đến trạng thái 400 và lỗi mạng trong Máy khách Apollo.

Apollo Client thực sự cung cấp bốn cách khác nhau để xử lý các lỗi đột biến:

1.) Gọi mutatehàm được trả về bởi hook trả về một Promise. Nếu yêu cầu thành công, Promise sẽ giải quyết đối tượng phản hồi bao gồm datamáy chủ trả về. Nếu yêu cầu không thành công, Promise sẽ từ chối với lỗi. Đây là lý do tại sao bạn thấy thông báo "Từ chối chưa xử lý" trong bảng điều khiển - bạn cần xử lý Lời hứa bị từ chối.

login()
  .then(({ data }) => {
    // you can do something with the response here
  })
  .catch(e => {
    // you can do something with the error here
  })

hoặc với cú pháp async / await:

try {
  const { data } = await login()
} catch (e) {
  // do something with the error here
}

Theo mặc định, Promise sẽ từ chối trên một trong hai lỗi GraphQL hoặc lỗi mạng. Tuy nhiên, bằng cách đặt errorPolicy thành ignorehoặc all, Promise sẽ chỉ từ chối các lỗi mạng. Trong trường hợp này, các lỗi GraphQL vẫn có thể truy cập được thông qua đối tượng phản hồi, nhưng Promise sẽ giải quyết.

2.) Ngoại lệ duy nhất ở trên xảy ra khi bạn cung cấp một onErrorchức năng. Trong trường hợp này, Promise sẽ luôn giải quyết thay vì từ chối, nhưng nếu xảy ra lỗi, onErrorsẽ được gọi với lỗi kết quả. Các errorPolicybạn thiết lập áp dụng ở đây quá - onErrorsẽ luôn luôn được gọi là lỗi mạng nhưng sẽ chỉ được gọi với các lỗi GraphQL khi sử dụng mặc định errorPolicycủa none. Việc sử dụng onErrortương đương với việc bắt Promise bị từ chối - nó chỉ di chuyển trình xử lý lỗi từ trang gọi của mutatechức năng sang trang gọi của hook.

3.) Ngoài mutatechức năng, useMutationhook cũng trả về một đối tượng kết quả. Đối tượng này cũng để lộ bất kỳ lỗi nào gặp phải khi chạy đột biến. Không giống như các hàm xử lý lỗi mà chúng ta đã viết ở trên, errorđối tượng này biểu thị trạng thái ứng dụng . Cả errordatacác đối tượng tiếp xúc theo cách này tồn tại như một sự thuận tiện. Chúng tương đương với việc này:

const [mutate] = useMutation(YOUR_MUTATION)
const [data, setData] = useState()
const [error, setError] = useState()
const handleClick = async () => {
  try {
    const { data } = await mutate()
    setData(data)
  catch (e) {
    setError(e)
  }
}

Có trạng thái lỗi như thế này có thể hữu ích khi bạn muốn UI của mình phản ánh thực tế là có lỗi. Ví dụ: bạn có thể thay đổi màu của một phần tử cho đến khi đột biến chạy mà không gặp lỗi. Thay vì phải tự viết bản tóm tắt ở trên, bạn chỉ có thể sử dụng đối tượng kết quả được cung cấp.

const [mutate, { data, error }] = useMutation(YOUR_MUTATION)

LƯU Ý: Mặc dù bạn có thể sử dụng trạng thái lỗi tiếp xúc để cập nhật giao diện người dùng của mình, nhưng làm như vậy không phải là sự thay thế cho việc xử lý lỗi thực sự . Bạn phải cung cấp một onErrorcuộc gọi lại hoặc catchlỗi để tránh cảnh báo về việc từ chối Promise chưa được xử lý.

4.) Cuối cùng, bạn cũng có thể sử dụng lỗi liên kết apol để thêm xử lý lỗi toàn cầu cho các yêu cầu của mình. Điều này cho phép bạn, ví dụ, hiển thị hộp thoại báo lỗi bất kể nơi nào trong ứng dụng của bạn yêu cầu bắt nguồn.

Những phương pháp nào bạn sử dụng trong ứng dụng của mình phụ thuộc rất nhiều vào những gì bạn đang cố gắng thực hiện (toàn cầu so với cục bộ, trạng thái so với gọi lại, v.v.). Hầu hết các ứng dụng sẽ sử dụng nhiều hơn một phương pháp xử lý lỗi.


Cảm ơn đã giải thích! Nâng cao!
Hyphæne Ohmen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.