【问题标题】:Unhandled runtime error or uncaught (in promise) error未处理的运行时错误或未捕获的(承诺中)错误
【发布时间】: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


    【解决方案1】:

    为了解决这个问题,我查看了更多的 apollo 文档:https://www.apollographql.com/docs/react/data/error-handling/

    我设置了一个错误策略:“全部”,以呈现错误信息和任何部分结果。

      const [addCategory, { data, loading, error }] = useMutation(ADD_CATEGORY, {
            errorPolicy: 'all',
            onCompleted: (data) => {
                if (data.addCategory) {
                    router.push('/user/menu');
                }
            },
        });
    

    我能够看到客户端的错误、控制台和浏览器上的静默错误,以及来自 Next.js 的任何错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-04
      • 2018-08-26
      • 1970-01-01
      • 2022-12-19
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 2021-11-28
      相关资源
      最近更新 更多