diff --git a/src/components/misc/ready.vue b/src/components/misc/ready.vue index 6bde50707..08616df1a 100644 --- a/src/components/misc/ready.vue +++ b/src/components/misc/ready.vue @@ -48,13 +48,14 @@ import Message from '@/components/misc/message.vue' import CustomTransition from '@/components/misc/CustomTransition.vue' import NoAuthWrapper from '@/components/misc/no-auth-wrapper.vue' -import {ERROR_NO_API_URL} from '@/helpers/checkAndSetApiUrl' +import {ERROR_NO_API_URL, InvalidApiUrlProvidedError, NoApiUrlProvidedError} from '@/helpers/checkAndSetApiUrl' import {useOnline} from '@/composables/useOnline' import {getAuthForRoute} from '@/router' import {useBaseStore} from '@/stores/base' import {useAuthStore} from '@/stores/auth' +import {useI18n} from 'vue-i18n' const router = useRouter() const route = useRoute() @@ -68,6 +69,8 @@ const online = useOnline() const error = ref('') const showLoading = computed(() => !ready.value && error.value === '') +const {t} = useI18n() + async function load() { try { await baseStore.loadApp() @@ -77,7 +80,15 @@ async function load() { await router.push(redirectTo) } } catch (e: unknown) { - error.value = String(e) + if (e instanceof NoApiUrlProvidedError) { + error.value = ERROR_NO_API_URL + return + } + if (e instanceof InvalidApiUrlProvidedError) { + error.value = t('apiConfig.error') + return + } + error.value = String(e.message) } } diff --git a/src/helpers/checkAndSetApiUrl.ts b/src/helpers/checkAndSetApiUrl.ts index f60de7fe7..1144dff27 100644 --- a/src/helpers/checkAndSetApiUrl.ts +++ b/src/helpers/checkAndSetApiUrl.ts @@ -4,8 +4,27 @@ const API_DEFAULT_PORT = '3456' export const ERROR_NO_API_URL = 'noApiUrlProvided' +export class NoApiUrlProvidedError extends Error { + constructor() { + super() + this.message = 'No API URL provided' + this.name = 'NoApiUrlProvidedError' + } +} + +export class InvalidApiUrlProvidedError extends Error { + constructor() { + super() + this.message = 'The provided API URL is invalid.' + this.name = 'InvalidApiUrlProvidedError' + } +} + +export const checkAndSetApiUrl = (url: string | undefined | null): Promise => { + if (url === '' || url === null || typeof url === 'undefined') { + throw new NoApiUrlProvidedError() + } -export const checkAndSetApiUrl = (url: string): Promise => { if (url.startsWith('/')) { url = window.location.host + url } @@ -17,8 +36,14 @@ export const checkAndSetApiUrl = (url: string): Promise => { ) { url = `${window.location.protocol}//${url}` } + + let urlToCheck: URL + try { + urlToCheck = new URL(url) + } catch (e) { + throw new InvalidApiUrlProvidedError() + } - const urlToCheck: URL = new URL(url) const origUrlToCheck = urlToCheck const oldUrl = window.API_URL @@ -86,6 +111,6 @@ export const checkAndSetApiUrl = (url: string): Promise => { return window.API_URL } - throw new Error(ERROR_NO_API_URL) + throw new InvalidApiUrlProvidedError() }) } diff --git a/src/i18n/lang/en.json b/src/i18n/lang/en.json index 9a342e64f..f8c43c5c5 100644 --- a/src/i18n/lang/en.json +++ b/src/i18n/lang/en.json @@ -916,7 +916,7 @@ "urlPlaceholder": "eg. https://localhost:3456", "change": "change", "use": "Using Vikunja installation at {0}", - "error": "Could not find or use Vikunja installation at \"{domain}\". Please try a different url.", + "error": "Could not find or use Vikunja installation at \"{domain}\". Please check if the url has the correct format and you can reach it when accessing it directly and try again.", "success": "Using Vikunja installation at \"{domain}\".", "urlRequired": "A url is required." },