react 和 apollo 中 graphql 突变挂钩的错误处理不起作用
Error Handling for graphql mutation hook in react and apollo not working
我似乎在我的代码中某处遗漏了一个配置,但似乎无法找到我做错了什么。
我们有一个简单的登录表单。
如果输入了正确的用户名和密码,没问题,应用程序继续运行。
但是,如果输入的用户名或密码不正确,Apollo 会在 DOM 上抛出错误。 "login" 函数包装在 try-catch 块中,但错误仍然显示在 DOM 上。
见下方截图:
const LoginForm = () => {
const classes = useStyles();
const [inputData, setInputData] = useState();
const { register, errors } = useForm({
mode: "onBlur",
validationSchema: LoginSchema,
});
const [login, { data, error }] = useMutation(LOGIN_MUTATION, {
errorPolicy: "all",
});
const handleLogin = (e) => {
try {
e.preventDefault();
login({
variables: {
identifier: inputData.email,
password: inputData.password,
},
});
} catch (err) {
console.log("There was an error");
}
};
if (error) {
console.log("ERRORSSSS: ", error.graphQLErrors);
return <h1>Error</h1>;
} else if (data) {
console.log(data);
}
const handleInput = (e) => {
setInputData({ ...inputData, [e.target.name]: e.target.value });
};
return (
<>
<Form onSubmit={handleLogin}>
<Grid container spacing={3}>
<Grid item xs={12} sm={12}>
<TextField
className={classes.width}
id="email"
name="email"
label="Email"
// fullWidth
inputRef={register({ required: true })}
onChange={handleInput}
error={errors.email ? true : null}
helperText={errors.email ? errors.email.message : null}
/>
</Grid>
<Grid item xs={12} sm={12}>
<TextField
className={classes.width}
id="password"
name="password"
label="Password"
// fullWidth
type="password"
inputRef={register({ required: true })}
onChange={handleInput}
/>
</Grid>
<Grid item xs={12} sm={12}>
<LoginButton
type="submit"
text="Login"
margin="1.5em 0 0 0"
bg="blue3"
/>
</Grid>
</Grid>
</Form>
</>
);
};
注意:
- 我们的后端使用 Strapi 3.0.1
- 以下是我们的 Apollo 客户端设置:
const errorLink = onError(
({ graphQLErrors, networkError, response, operation }) => {
if (graphQLErrors) {
if (operation.operationName === "IgnoreErrorsQuery") {
response.errors = undefined;
}
graphQLErrors.map(({ message, locations, path }) => {
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
);
});
}
if (networkError) console.log(`[Network error]: ${networkError}`);
}
);
const httpLink = new HttpLink({ uri: "http://localhost:1337/graphql" });
const link = ApolloLink.from([errorLink, httpLink]);
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
});
控制台告诉我们有一个未捕获的承诺。您的 login 函数是一个 Promise,因此您需要使用 then/catch。像这样:
const handleLogin = (e) => {
e.preventDefault();
login({
variables: {
identifier: inputData.email,
password: inputData.password,
},
})
.then(v => console.log(v))
.catch(e => console.log(e))
};
我似乎在我的代码中某处遗漏了一个配置,但似乎无法找到我做错了什么。
我们有一个简单的登录表单。
如果输入了正确的用户名和密码,没问题,应用程序继续运行。
但是,如果输入的用户名或密码不正确,Apollo 会在 DOM 上抛出错误。 "login" 函数包装在 try-catch 块中,但错误仍然显示在 DOM 上。
见下方截图:
const LoginForm = () => {
const classes = useStyles();
const [inputData, setInputData] = useState();
const { register, errors } = useForm({
mode: "onBlur",
validationSchema: LoginSchema,
});
const [login, { data, error }] = useMutation(LOGIN_MUTATION, {
errorPolicy: "all",
});
const handleLogin = (e) => {
try {
e.preventDefault();
login({
variables: {
identifier: inputData.email,
password: inputData.password,
},
});
} catch (err) {
console.log("There was an error");
}
};
if (error) {
console.log("ERRORSSSS: ", error.graphQLErrors);
return <h1>Error</h1>;
} else if (data) {
console.log(data);
}
const handleInput = (e) => {
setInputData({ ...inputData, [e.target.name]: e.target.value });
};
return (
<>
<Form onSubmit={handleLogin}>
<Grid container spacing={3}>
<Grid item xs={12} sm={12}>
<TextField
className={classes.width}
id="email"
name="email"
label="Email"
// fullWidth
inputRef={register({ required: true })}
onChange={handleInput}
error={errors.email ? true : null}
helperText={errors.email ? errors.email.message : null}
/>
</Grid>
<Grid item xs={12} sm={12}>
<TextField
className={classes.width}
id="password"
name="password"
label="Password"
// fullWidth
type="password"
inputRef={register({ required: true })}
onChange={handleInput}
/>
</Grid>
<Grid item xs={12} sm={12}>
<LoginButton
type="submit"
text="Login"
margin="1.5em 0 0 0"
bg="blue3"
/>
</Grid>
</Grid>
</Form>
</>
);
};
注意: - 我们的后端使用 Strapi 3.0.1 - 以下是我们的 Apollo 客户端设置:
const errorLink = onError(
({ graphQLErrors, networkError, response, operation }) => {
if (graphQLErrors) {
if (operation.operationName === "IgnoreErrorsQuery") {
response.errors = undefined;
}
graphQLErrors.map(({ message, locations, path }) => {
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
);
});
}
if (networkError) console.log(`[Network error]: ${networkError}`);
}
);
const httpLink = new HttpLink({ uri: "http://localhost:1337/graphql" });
const link = ApolloLink.from([errorLink, httpLink]);
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
});
控制台告诉我们有一个未捕获的承诺。您的 login 函数是一个 Promise,因此您需要使用 then/catch。像这样:
const handleLogin = (e) => {
e.preventDefault();
login({
variables: {
identifier: inputData.email,
password: inputData.password,
},
})
.then(v => console.log(v))
.catch(e => console.log(e))
};