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ó errors
trong 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 mutate
hà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 data
má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 ignore
hoặ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 onError
chứ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, onError
sẽ được gọi với lỗi kết quả. Các errorPolicy
bạn thiết lập áp dụng ở đây quá - onError
sẽ 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 errorPolicy
của none
. Việc sử dụng onError
tươ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 mutate
chức năng sang trang gọi của hook.
3.) Ngoài mutate
chức năng, useMutation
hook 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ả error
và data
cá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 onError
cuộc gọi lại hoặc catch
lỗ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.