0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

feat(console): wrap ky to handle response error (#370)

* feat(console): wrap ky to handle response error

* fix: handle error without body
This commit is contained in:
Wang Sijie 2022-03-14 11:17:04 +08:00 committed by GitHub
parent 043b20a05a
commit 74d7dd6603
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 47 additions and 15 deletions

View file

@ -1,5 +1,4 @@
import { Resource } from '@logto/schemas';
import ky from 'ky';
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
@ -15,6 +14,7 @@ import ImagePlaceholder from '@/components/ImagePlaceholder';
import TabNav, { TabNavLink } from '@/components/TabNav';
import TextInput from '@/components/TextInput';
import { RequestError } from '@/swr';
import api from '@/utilities/api';
import * as styles from './index.module.scss';
@ -50,7 +50,7 @@ const ApiResourceDetails = () => {
setSubmitting(true);
try {
const updatedApiResource = await ky
const updatedApiResource = await api
.patch(`/api/resources/${data.id}`, { json: formData })
.json<Resource>();
void mutate(updatedApiResource);

View file

@ -1,5 +1,4 @@
import { Resource } from '@logto/schemas';
import ky from 'ky';
import React from 'react';
import { useForm } from 'react-hook-form';
@ -9,6 +8,7 @@ import CardTitle from '@/components/CardTitle';
import FormField from '@/components/FormField';
import TextInput from '@/components/TextInput';
import Close from '@/icons/Close';
import api from '@/utilities/api';
import * as styles from './index.module.scss';
@ -26,7 +26,7 @@ const CreateForm = ({ onClose }: Props) => {
const onSubmit = handleSubmit(async (data) => {
try {
const createdApiResource = await ky.post('/api/resources', { json: data }).json<Resource>();
const createdApiResource = await api.post('/api/resources', { json: data }).json<Resource>();
onClose?.(createdApiResource);
} catch (error: unknown) {
console.error(error);

View file

@ -1,5 +1,4 @@
import { Application, ApplicationType } from '@logto/schemas';
import ky from 'ky';
import React from 'react';
import { useController, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
@ -12,6 +11,7 @@ import RadioGroup, { Radio } from '@/components/RadioGroup';
import TextInput from '@/components/TextInput';
import Close from '@/icons/Close';
import { applicationTypeI18nKey } from '@/types/applications';
import api from '@/utilities/api';
import TypeDescription from '../TypeDescription';
import * as styles from './index.module.scss';
@ -40,7 +40,7 @@ const CreateForm = ({ onClose }: Props) => {
const onSubmit = handleSubmit(async (data) => {
try {
const createdApp = await ky.post('/api/applications', { json: data }).json<Application>();
const createdApp = await api.post('/api/applications', { json: data }).json<Application>();
onClose?.(createdApp);
} catch (error: unknown) {

View file

@ -1,5 +1,4 @@
import { ConnectorDTO, ConnectorType, RequestErrorBody } from '@logto/schemas';
import ky, { HTTPError } from 'ky';
import { ConnectorDTO, ConnectorType } from '@logto/schemas';
import React, { useEffect, useState } from 'react';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
@ -17,6 +16,7 @@ import TabNav, { TabNavLink } from '@/components/TabNav';
import Close from '@/icons/Close';
import * as drawerStyles from '@/scss/drawer.module.scss';
import { RequestError } from '@/swr';
import api from '@/utilities/api';
import SenderTester from './components/SenderTester';
import * as styles from './index.module.scss';
@ -56,18 +56,15 @@ const ConnectorDetails = () => {
try {
const configJson = JSON.parse(config) as JSON;
setIsSubmitLoading(true);
await ky
.patch(`/api/connectors/${connectorId}`, { json: { config: configJson } })
await api
.patch(`/api/connectors/${connectorId}`, {
json: { config: configJson },
})
.json<ConnectorDTO>();
toast.success(t('connector_details.save_success'));
} catch (error: unknown) {
if (error instanceof SyntaxError) {
setSaveError(t('connector_details.save_error_json_parse_error'));
} else if (error instanceof HTTPError) {
const { message } = (await error.response.json()) as RequestErrorBody;
setSaveError(message);
} else {
console.error(error);
}
}

View file

@ -0,0 +1,29 @@
import { RequestErrorBody } from '@logto/schemas';
import { t } from 'i18next';
import ky from 'ky';
import { toast } from 'react-hot-toast';
const toastError = async (response: Response) => {
try {
const data = (await response.json()) as RequestErrorBody;
toast.error(data.message || t('admin_console.errors.unknown_server_error'));
} catch {
toast.error(t('admin_console.errors.unknown_server_error'));
}
};
const api = ky.create({
hooks: {
beforeError: [
(error) => {
const { response } = error;
void toastError(response);
return error;
},
],
},
});
export default api;

View file

@ -25,6 +25,9 @@ const translation = {
form: {
required: 'Required',
},
errors: {
unknown_server_error: 'Unknown server error occurred.',
},
tab_sections: {
overview: 'Overview',
resource_management: 'Resource Management',

View file

@ -27,6 +27,9 @@ const translation = {
form: {
required: '必填',
},
errors: {
unknown_server_error: '服务器发生未知错误。',
},
tab_sections: {
overview: '概览',
resource_management: '资源管理',