diff --git a/src/backend/router.ts b/src/backend/router.ts
index 93cae67..04b10ce 100644
--- a/src/backend/router.ts
+++ b/src/backend/router.ts
@@ -29,7 +29,17 @@ router.get('/login', async ctx => {
return;
}
- const meta = await api<{ name: string, uri: string, version: string, features: Record }>(host, 'meta', {});
+ // http://, https://を潰す
+ host = host.trim().replace(/^https?:\/\//g, '').replace(/\/+/g, '');
+
+ const meta = await api<{ name: string, uri: string, version: string, features: Record }>(host, 'meta', {}).catch(async e => {
+ if (!(e instanceof Error && e.name === 'Error')) throw e;
+ await die(ctx, 'hostNotFound');
+ });
+
+ // NOTE: catchが呼ばれた場合はvoidとなるためundefinedのはず
+ if (typeof meta === 'undefined') return;
+
if (typeof meta !== 'object') {
await die(ctx, 'other');
return;
@@ -40,9 +50,6 @@ router.get('/login', async ctx => {
return;
}
- // ホスト名の正規化
- host = meta.uri.replace(/^https?:\/\//, '');
-
const { name, permission, description } = misskeyAppInfo;
if (meta.features.miauth) {
diff --git a/src/common/types/error-code.ts b/src/common/types/error-code.ts
index dc0ec26..db462d4 100644
--- a/src/common/types/error-code.ts
+++ b/src/common/types/error-code.ts
@@ -5,6 +5,8 @@ export const errorCodes = [
'tokenRequired',
'invalidParamater',
'notAuthorized',
+ 'hostNotFound',
+ 'invalidHostFormat',
'other',
] as const;
diff --git a/src/frontend/App.tsx b/src/frontend/App.tsx
index fc6a1de..10e79be 100644
--- a/src/frontend/App.tsx
+++ b/src/frontend/App.tsx
@@ -1,5 +1,5 @@
-import React, { useEffect } from 'react';
-import { BrowserRouter, useLocation } from 'react-router-dom';
+import React, { useEffect, useState } from 'react';
+import { BrowserRouter, Link, useLocation } from 'react-router-dom';
import { Provider, useDispatch } from 'react-redux';
import { useTranslation } from 'react-i18next';
@@ -22,7 +22,18 @@ const AppInner : React.VFC = () => {
const {t} = useTranslation();
- const error = (window as any).__misshaialert?.error;
+ const [error, setError] = useState((window as any).__misshaialert?.error);
+
+ // ページ遷移がまだされていないかどうか
+ const [isFirstView, setFirstView] = useState(true);
+
+ useEffect(() => {
+ if (isFirstView) {
+ setFirstView(false);
+ } else if (!isFirstView && error) {
+ setError(null);
+ }
+ }, [$location]);
useEffect(() => {
const qMobile = window.matchMedia(`(max-width: ${BREAKPOINT_SM})`);
@@ -47,6 +58,7 @@ const AppInner : React.VFC = () => {
{t('_error.additionalInfo')}
{t(`_error.${error}`)}
+ {t('retry')}
) : }