【发布时间】:2021-10-02 15:31:15
【问题描述】:
我试图确保 Next.js 不显示错误,而是在我的代码中处理它。我正在使用 Apollo-client 来处理错误,并且我正在密切关注文档以确保我正在正确处理它们。我目前收到 Next.js 显示的“未处理的运行时错误。错误:类别已存在”,在 Chrome 浏览器控制台上,我收到“未捕获(承诺)错误:类别已存在”。但是,我确实注意到该错误出现在我的浏览器上,但我只是不希望出现 Next.js 错误。
我尝试重新组织我的代码,以便错误状态不必经过太多子组件。如果类别存在,我尝试将错误的类型从 UserInputError 更改为 ApolloError。我不确定我做错了什么。请帮忙。
这是我的代码:
这是我从后端获取数据的代码:
const addCategory = async ({ user_id, name }) => {
await authorizeActivity({ user_id });
const categoryExists = await getCategory({ name, user_id });
if (categoryExists)
throw new UserInputError('The category name already exists');
const newCategory = await db
.insert({ user_id, name }, '*')
.into('category');
if (!newCategory[0]) {
throw new ApolloError('Something went wrong!');
}
return newCategory[0];
};
这是我的页面。请注意,我将错误和加载状态传递给表单组件:
export default function NewCategory() {
const router = useRouter();
const user_id = Cookies.get('user');
const {
handleSubmit,
register,
formState: { errors, isDirty },
} = useForm();
const [addCategory, { data, loading, error }] = useMutation(ADD_CATEGORY);
useEffect(() => {
if (data) {
router.push('/user/menu');
}
}, [data]);
const onSubmit = (data) => {
addCategory({
variables: {
user_id,
name: data.category,
},
});
};
return (
<Layout>
<Form
formState={isDirty}
navigate={{
prev: {
message:
'Your changes will not be saved. Are you sure?',
link: '/user/menu',
},
}}
title={'Add new category'}
onSubmit={handleSubmit(onSubmit)}
button={
<button
type="submit"
style={{
padding: '16px 23px',
width: '100%',
maxWidth: '500px',
borderRadius: '8px',
marginTop: '10px',
}}
>
Add
</button>
}
state={{ loading, error }}
>
<Field
register={register('category', { required: 'Required' })}
info={{ name: 'category', label: 'Name' }}
errors={
errors.category
? errors.category.message
: errors.category
}
/>
</Form>
</Layout>
);
}
这是我的表单组件:
export const Form = ({
onSubmit,
children,
title,
footer,
state,
button,
className,
navigate,
formState,
}) => {
const [warn, setWarn] = useState(false);
const [warnMessage, setWarnMessage] = useState({ toggle: setWarn });
const warning = ({ message, link, toggle }) => (
<Alert
pop
dismissible={() => toggle(false)}
state="warning"
message={
<>
{message}{' '}
<Link href={link} passHref>
<a
style={{
fontWeight: '400',
textDecoration: 'underline',
}}
>
Yes.
</a>
</Link>
</>
}
/>
);
return (
<>
{navigate ? (
<div className={styles.navigate}>
{navigate.prev && (
<RiArrowLeftCircleLine
onClick={() => {
if (formState) {
setWarnMessage({
...warnMessage,
...navigate.prev,
});
setWarn(!warn);
} else {
router.push(navigate.prev.link);
}
}}
/>
)}
{navigate.next && (
<RiArrowRightCircleLine onClick={navigate.next} />
)}
</div>
) : null}
{warn ? warning(warnMessage, setWarn) : null}
<div className={styles.form_wrapper}>
{(title && <div className={styles.form_title}>{title}</div>) ||
null}
<form
onSubmit={onSubmit}
className={`${styles.form_inner} ${className || ''}`}
>
{children}
{state &&
(state.loading || state.error || state.warning) ? (
<div className={styles.form_state}>
{state.loading ? (
<Loading />
) : state.error ? (
<Alert
state="error"
message={
state.error?.message ||
'Something went wrong'
}
/>
) : state.warning ? (
<Alert
state="warning"
message={state.warning.message}
/>
) : null}
</div>
) : null}
{button || null}
</form>
{(footer && (
<div className={styles.form_footer}>{footer}</div>
)) ||
null}
</div>
</>
);
};
【问题讨论】:
标签: reactjs graphql next.js apollo-client