mirror of
https://github.com/MisskeyIO/misskey
synced 2024-11-30 15:58:16 +09:00
enhance(frontend): 定義されていないエラーも表示できるように (MisskeyIO#738)
+登録時のAPIエラーを表示できるように
This commit is contained in:
parent
c82bf7583a
commit
69f31e6246
@ -189,7 +189,7 @@ async function onSubmit(): Promise<void> {
|
|||||||
submitting.value = true;
|
submitting.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await misskeyApi('signup', {
|
await os.apiWithDialog('signup', {
|
||||||
username: username.value,
|
username: username.value,
|
||||||
password: password.value.password,
|
password: password.value.password,
|
||||||
emailAddress: email.value,
|
emailAddress: email.value,
|
||||||
@ -198,35 +198,27 @@ async function onSubmit(): Promise<void> {
|
|||||||
'm-captcha-response': mCaptchaResponse.value,
|
'm-captcha-response': mCaptchaResponse.value,
|
||||||
'g-recaptcha-response': reCaptchaResponse.value,
|
'g-recaptcha-response': reCaptchaResponse.value,
|
||||||
'turnstile-response': turnstileResponse.value,
|
'turnstile-response': turnstileResponse.value,
|
||||||
});
|
}, undefined, (res) => {
|
||||||
if (instance.emailRequiredForSignup) {
|
if (instance.emailRequiredForSignup) {
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
title: i18n.ts._signup.almostThere,
|
title: i18n.ts._signup.almostThere,
|
||||||
text: i18n.tsx._signup.emailSent({ email: email.value }),
|
text: i18n.tsx._signup.emailSent({ email: email.value }),
|
||||||
});
|
});
|
||||||
emit('signupEmailPending');
|
emit('signupEmailPending');
|
||||||
} else {
|
} else {
|
||||||
const res = await misskeyApi('signin', {
|
emit('signup', { id: res.id, i: res.token });
|
||||||
username: username.value,
|
|
||||||
password: password.value.password,
|
|
||||||
});
|
|
||||||
emit('signup', res);
|
|
||||||
|
|
||||||
if (props.autoSet) {
|
if (props.autoSet) {
|
||||||
return login(res.i);
|
login(res.token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
} catch {
|
} catch {
|
||||||
submitting.value = false;
|
submitting.value = false;
|
||||||
hcaptcha.value?.reset?.();
|
hcaptcha.value?.reset?.();
|
||||||
recaptcha.value?.reset?.();
|
recaptcha.value?.reset?.();
|
||||||
turnstile.value?.reset?.();
|
turnstile.value?.reset?.();
|
||||||
|
|
||||||
os.alert({
|
|
||||||
type: 'error',
|
|
||||||
text: i18n.ts.somethingHappened,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -34,60 +34,77 @@ export const apiWithDialog = (<E extends keyof Misskey.Endpoints = keyof Misskey
|
|||||||
endpoint: E,
|
endpoint: E,
|
||||||
data: P = {} as P,
|
data: P = {} as P,
|
||||||
token?: string | null | undefined,
|
token?: string | null | undefined,
|
||||||
) => {
|
onSuccess?: ((res: Misskey.api.SwitchCaseResponseType<E, P>) => void) | null | undefined,
|
||||||
|
onFailure?: ((err: Misskey.api.APIError) => void) | null,
|
||||||
|
): Promise<Misskey.api.SwitchCaseResponseType<E, P>> => {
|
||||||
const promise = misskeyApi(endpoint, data, token);
|
const promise = misskeyApi(endpoint, data, token);
|
||||||
promiseDialog(promise, null, async (err) => {
|
promiseDialog(promise, onSuccess, onFailure ?? (err => apiErrorHandler(err, endpoint)));
|
||||||
let title: string | undefined;
|
|
||||||
let text = err.message + '\n' + err.id;
|
return promise;
|
||||||
if (err.code === 'INTERNAL_ERROR') {
|
});
|
||||||
title = i18n.ts.internalServerError;
|
|
||||||
text = i18n.ts.internalServerErrorDescription;
|
export async function apiErrorHandler(err: Misskey.api.APIError, endpoint?: string): Promise<void> {
|
||||||
const date = new Date().toISOString();
|
let title: string | undefined;
|
||||||
const { result } = await actions({
|
let text = err.message + '\n' + err.id;
|
||||||
type: 'error',
|
|
||||||
title,
|
if (err.code === 'INTERNAL_ERROR') {
|
||||||
text,
|
title = i18n.ts.internalServerError;
|
||||||
details: err.info,
|
text = i18n.ts.internalServerErrorDescription;
|
||||||
actions: [{
|
const date = new Date().toISOString();
|
||||||
value: 'ok',
|
const { result } = await actions({
|
||||||
text: i18n.ts.gotIt,
|
|
||||||
primary: true,
|
|
||||||
}, {
|
|
||||||
value: 'copy',
|
|
||||||
text: i18n.ts.copyErrorInfo,
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
if (result === 'copy') {
|
|
||||||
copyToClipboard(`Endpoint: ${endpoint}\nInfo: ${JSON.stringify(err.info)}\nDate: ${date}`);
|
|
||||||
success();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (err.code === 'RATE_LIMIT_EXCEEDED') {
|
|
||||||
title = i18n.ts.cannotPerformTemporary;
|
|
||||||
text = i18n.ts.cannotPerformTemporaryDescription;
|
|
||||||
} else if (err.code === 'INVALID_PARAM') {
|
|
||||||
title = i18n.ts.invalidParamError;
|
|
||||||
text = i18n.ts.invalidParamErrorDescription;
|
|
||||||
} else if (err.code === 'ROLE_PERMISSION_DENIED') {
|
|
||||||
title = i18n.ts.permissionDeniedError;
|
|
||||||
text = i18n.ts.permissionDeniedErrorDescription;
|
|
||||||
} else if (err.code.startsWith('TOO_MANY')) {
|
|
||||||
title = i18n.ts.youCannotCreateAnymore;
|
|
||||||
text = `${i18n.ts.error}: ${err.id}`;
|
|
||||||
} else if (err.message.startsWith('Unexpected token')) {
|
|
||||||
title = i18n.ts.gotInvalidResponseError;
|
|
||||||
text = i18n.ts.gotInvalidResponseErrorDescription;
|
|
||||||
}
|
|
||||||
alert({
|
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title,
|
title,
|
||||||
text,
|
text,
|
||||||
details: err.info,
|
details: err.info,
|
||||||
|
actions: [{
|
||||||
|
value: 'ok',
|
||||||
|
text: i18n.ts.gotIt,
|
||||||
|
primary: true,
|
||||||
|
}, {
|
||||||
|
value: 'copy',
|
||||||
|
text: i18n.ts.copyErrorInfo,
|
||||||
|
}],
|
||||||
});
|
});
|
||||||
});
|
if (result === 'copy') {
|
||||||
|
copyToClipboard(`Endpoint: ${endpoint}\nInfo: ${JSON.stringify(err.info)}\nDate: ${date}`);
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (err.code === 'RATE_LIMIT_EXCEEDED') {
|
||||||
|
title = i18n.ts.cannotPerformTemporary;
|
||||||
|
text = i18n.ts.cannotPerformTemporaryDescription;
|
||||||
|
} else if (err.code === 'INVALID_PARAM') {
|
||||||
|
title = i18n.ts.invalidParamError;
|
||||||
|
text = i18n.ts.invalidParamErrorDescription;
|
||||||
|
} else if (err.code === 'ROLE_PERMISSION_DENIED') {
|
||||||
|
title = i18n.ts.permissionDeniedError;
|
||||||
|
text = i18n.ts.permissionDeniedErrorDescription;
|
||||||
|
} else if (err.code?.startsWith('TOO_MANY')) {
|
||||||
|
title = i18n.ts.youCannotCreateAnymore;
|
||||||
|
text = `${i18n.ts.error}: ${err.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
return promise;
|
// @ts-expect-error Misskey内部で定義されていない不明なエラー
|
||||||
}) as typeof misskeyApi;
|
if (!err.id && (err.statusCode ?? 0) > 499) {
|
||||||
|
title = i18n.ts.gotInvalidResponseError;
|
||||||
|
text = i18n.ts.gotInvalidResponseErrorDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err.id && !title) {
|
||||||
|
title = i18n.ts.somethingHappened;
|
||||||
|
} else if (!title) {
|
||||||
|
title = i18n.ts.somethingHappened;
|
||||||
|
text = err.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert({
|
||||||
|
type: 'error',
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
// @ts-expect-error Misskeyのエラーならinfoを、そうでなければそのまま表示
|
||||||
|
details: err.id ? err.info : err as unknown,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function promiseDialog<T>(
|
export function promiseDialog<T>(
|
||||||
promise: Promise<T>,
|
promise: Promise<T>,
|
||||||
|
@ -44,14 +44,15 @@ export function misskeyApi<
|
|||||||
},
|
},
|
||||||
signal,
|
signal,
|
||||||
}).then(async (res) => {
|
}).then(async (res) => {
|
||||||
const body = res.status === 204 ? null : await res.json();
|
if (res.ok && res.status !== 204) {
|
||||||
|
const body = await res.json();
|
||||||
if (res.status === 200) {
|
|
||||||
resolve(body);
|
resolve(body);
|
||||||
} else if (res.status === 204) {
|
} else if (res.status === 204) {
|
||||||
resolve(undefined as _ResT); // void -> undefined
|
resolve(undefined as _ResT); // void -> undefined
|
||||||
} else {
|
} else {
|
||||||
reject(body.error);
|
// エラー応答で JSON.parse に失敗した場合は HTTP ステータスコードとメッセージを返す
|
||||||
|
const body = await res.json().catch(() => ({ statusCode: res.status, message: res.statusText }));
|
||||||
|
reject(typeof body.error === 'object' ? body.error : body);
|
||||||
}
|
}
|
||||||
}).catch(reject);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user