我对 vue-apollo 错误处理的概述。
SmartQuery 错误处理程序
文档:https://apollo.vuejs.org/api/smart-query.html
error(error, vm, key, type, options) 是一个钩子,当有
错误。 error 是带有 graphQLErrors 的 Apollo 错误对象
属性或 networkError 属性。 vm 是相关组件
实例。 key 是智能查询键。类型是“查询”或
'订阅'。 options 是最终的 watchQuery 选项对象。
未记录:如果您返回 false,则错误处理将停止,并且不会调用默认错误处理程序(Apollo Provider)。如果您返回 true 或不返回任何内容(又名 undefined),则会调用默认错误处理程序。
代码示例
export default {
name: "ProductWrapper",
props: ['productId'],
apollo: {
product: {
query: productQuery,
variables() {
return {
productId: this.productId
}
},
error(errors) {
console.log("Smart Query Error Handler")
console.log(errors.graphQLErrors)
return false;
}
}
}
}
VueApolloProvider 错误处理程序
文档: https://apollo.vuejs.org/api/apollo-provider.html
所有智能查询和订阅的全局错误处理程序
重要提示:这不适用于突变。
未记录:当智能查询的错误处理程序返回 false
时不会调用它
代码示例
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
errorHandler: (errors) => {
console.log("Provider errorHandler")
console.log(errors)
}
});
VueApolloProvider $error 特殊选项(无用)
文档
https://apollo.vuejs.org/guide/apollo/special-options.html
$error 在默认处理程序中捕获错误(有关智能查询,请参阅错误高级选项>)
代码示例(错误)
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
error(errors) {
console.log("Provider $error")
console.log(errors)
}
}
});
这是我的第一次尝试,但它会在安装组件时调用并为我们提供完整的组件。见https://github.com/vuejs/vue-apollo/issues/126
代码示例(可以吗?)
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$error() {
return (errors) => {
console.log("Provider $error handler")
console.log(errors.graphQLErrors)
}
},
},
});
这样调用 $error 函数。
但它就像默认的 errorHandler 一样被调用(见上文)。文档似乎是错误的。所以这个方法对我来说似乎没什么用。正如您在此调试屏幕截图中所见,它的使用方式与其他错误处理程序一样:
错误链接
文档: https://www.apollographql.com/docs/react/data/error-handling/#advanced-error-handling-with-apollo-link
代码示例
import {onError} from "apollo-link-error";
const errorHandler = onError(({ networkError, graphQLErrors }) => {
console.log("Link onError")
console.log({ graphQLErrors, networkError})
})
const link = split(
// split based on operation type
({query}) => {
const definition = getMainDefinition(query);
return definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
},
wsErrorHandler.concat(wsLink),
errorHandler.concat(httpLink)
);
重要:在任何其他 ErrorHandler 之前调用它,它适用于查询、订阅和突变
突变捕获
文档 https://apollo.vuejs.org/guide/apollo/mutations.html
代码示例 1
async submit() {
await this.$apollo.mutate({
mutation: productDeleteMutation,
variables: {
productId: this.product.id
},
}).catch((errors) => {
console.log("mutation .catch error")
console.log(errors)
})
}
代码示例 2
你也可以使用 try/catch:
async submit() {
try {
await this.$apollo.mutate({
mutation: productDeleteMutation,
variables: {
productId: this.product.id
},
})
} catch (errors) {
console.log("mutation try/catch error")
console.log(errors)
}
}
唯一可以调用的其他处理程序是 onError ErrorLink(见上文),它将在捕获错误处理之前调用。
vue 处理带有 errorCaptured 的突变
将此生命周期钩子添加到您的组件以捕获来自突变的错误。
errorCaptured(err, vm, info) {
console.log("errorCaptured")
console.log(err.graphQLErrors)
return false
}
文档:https://vuejs.org/v2/api/#errorCaptured
更多链接:https://medium.com/js-dojo/error-exception-handling-in-vue-js-application-6c26eeb6b3e4
它仅适用于突变,因为智能查询的错误由 apollo 自己处理。
vue 全局 errorHandler 的变异错误
你可以有一个 vue 默认的错误处理程序来捕获来自突变的 graphql 错误
import Vue from 'vue';
Vue.config.errorHandler = (err, vm, info) => {
if (err.graphQLErrors) {
console.log("vue errorHandler")
console.log(err.graphQLErrors)
}
};
它仅适用于突变,因为智能查询的错误由 apollo 自己处理。
文档 https://vuejs.org/v2/api/#errorHandler
window.onerror
vue 之外的错误可以用纯 javascript 处理
window.onerror = function(message, source, lineno, colno, error) {
if (error.graphQLErrors) {
console.log("window.onerror")
console.log(error.graphQLErrors)
}
};
这不适用于 vue 组件内部或外部的突变、查询或订阅,因为这些是由 vue 或 apollo 本身处理的(如果未处理,则会打印到 console.err)
文档 https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
总结
同时捕获突变和查询错误的唯一方法是使用 ApolloLink 的 onError。服务器、网络和身份验证错误应该在那里被捕获,因为这些不是特定于任何操作的。
补充说明
探讨如何处理后端的错误
https://blog.logrocket.com/handling-graphql-errors-like-a-champ-with-unions-and-interfaces/