diff --git a/src/components/Dashboard/Tiles/Apps/AppPing.tsx b/src/components/Dashboard/Tiles/Apps/AppPing.tsx index ca12c424b..cbdd8c959 100644 --- a/src/components/Dashboard/Tiles/Apps/AppPing.tsx +++ b/src/components/Dashboard/Tiles/Apps/AppPing.tsx @@ -1,5 +1,5 @@ import { Box, Indicator, Tooltip } from '@mantine/core'; -import { IconCheck, IconCheckbox, IconDownload, IconLoader, IconX } from '@tabler/icons-react'; +import { IconCheck, IconLoader, IconX } from '@tabler/icons-react'; import Consola from 'consola'; import { TargetAndTransition, Transition, motion } from 'framer-motion'; import { useTranslation } from 'next-i18next'; @@ -19,12 +19,15 @@ export const AppPing = ({ app }: AppPingProps) => { (config?.settings.customization.layout.enabledPing && app.network.enabledStatusChecker) ?? false; - const { data, isLoading, isFetching, isSuccess } = api.app.ping.useQuery(app.id, { + const { data, isFetching, isError, error } = api.app.ping.useQuery(app.id, { retry: false, enabled: active, select: (data) => { const isOk = getIsOk(app, data.status); - Consola.info(`Ping ${app.name} (${app.url}) ${data.status} ${isOk}`); + if (isOk) + Consola.info(`Ping of app "${app.name}" (${app.url}) returned ${data.status} (Accepted)`); + else + Consola.warn(`Ping of app "${app.name}" (${app.url}) returned ${data.status} (Refused)`); return { status: data.status, state: isOk ? ('online' as const) : ('down' as const), @@ -35,7 +38,7 @@ export const AppPing = ({ app }: AppPingProps) => { if (!active) return null; - const isOnline = data?.state === 'online'; + const isOnline = isError ? false : data?.state === 'online'; const disablePulse = config?.settings.customization.accessibility?.disablePingPulse ?? false; const replaceDotWithIcon = @@ -55,6 +58,12 @@ export const AppPing = ({ app }: AppPingProps) => { ease: 'easeInOut', }; + const label = () => { + if (isFetching) return t('states.loading'); + if (isError) return error?.message; + if (data?.state === 'online') return t('states.online', { response: data?.status ?? 'N/A' }); + return `${data?.statusText}: ${data?.status} (denied)`; + } return ( { {config?.settings.customization.accessibility?.replacePingDotsWithIcons ? ( - + ) : ( )} @@ -113,9 +116,7 @@ const AccessibleIndicatorPing = ({ export const getIsOk = (app: AppType, status: number) => { if (app.network.okStatus === undefined || app.network.statusCodes.length >= 1) { - Consola.log('Using new status codes'); return app.network.statusCodes.includes(status.toString()); } - Consola.warn('Using deprecated okStatus'); return app.network.okStatus.includes(status); }; diff --git a/src/pages/api/modules/ping.ts b/src/pages/api/modules/ping.ts deleted file mode 100644 index 4b2c13bea..000000000 --- a/src/pages/api/modules/ping.ts +++ /dev/null @@ -1,40 +0,0 @@ -import axios, { AxiosError } from 'axios'; -import Consola from 'consola'; -import https from 'https'; -import { NextApiRequest, NextApiResponse } from 'next'; - -async function Get(req: NextApiRequest, res: NextApiResponse) { - // Parse req.body as a AppItem - const { url } = req.query; - const agent = new https.Agent({ rejectUnauthorized: false }); - await axios - .get(url as string, { httpsAgent: agent, timeout: 2000 }) - .then((response) => { - res.status(response.status).json(response.statusText); - }) - .catch((error: AxiosError) => { - if (error.response) { - Consola.warn(`Unexpected response: ${error.message}`); - res.status(error.response.status).json(error.response.statusText); - } else if (error.code === 'ECONNABORTED') { - res.status(408).json('Request Timeout'); - } else { - Consola.error(`Unexpected error: ${error.message}`); - res.status(500).json('Internal Server Error'); - } - }); - // // Make a request to the URL - // const response = await axios.get(url); - // // Return the response -} - -export default async (req: NextApiRequest, res: NextApiResponse) => { - // Filter out if the reuqest is a POST or a GET - if (req.method === 'GET') { - return Get(req, res); - } - return res.status(405).json({ - statusCode: 405, - message: 'Method not allowed', - }); -}; diff --git a/src/server/api/routers/app.ts b/src/server/api/routers/app.ts index 17a4ae06d..4e403c0ca 100644 --- a/src/server/api/routers/app.ts +++ b/src/server/api/routers/app.ts @@ -10,12 +10,6 @@ import { AppType } from '~/types/app'; import { createTRPCRouter, publicProcedure } from '../trpc'; -const errorResponse = { - state: 'offline', - status: 500, - statusText: 'Check logs for more informations', -}; - export const appRouter = createTRPCRouter({ ping: publicProcedure.input(z.string()).query(async ({ input }) => { const agent = new https.Agent({ rejectUnauthorized: false }); @@ -26,7 +20,11 @@ export const appRouter = createTRPCRouter({ const url = app?.url; if (url === undefined || !app) { Consola.error(`App ${input} not found`); - return errorResponse; + throw new TRPCError({ + code: 'NOT_FOUND', + cause: input, + message: `App ${input} was not found`, + }); } const res = await axios .get(url, { httpsAgent: agent, timeout: 2000 }) @@ -44,12 +42,20 @@ export const appRouter = createTRPCRouter({ } if (error.code === 'ECONNABORTED') { - Consola.error(`Ping timeout for ${input}`); - return errorResponse; + Consola.error(`Ping timed out for app with id : ${input} (url: ${url})`); + throw new TRPCError({ + code: 'TIMEOUT', + cause: input, + message: `Ping timed out`, + }); } Consola.error(`Unexpected response: ${error.message}`); - return errorResponse; + throw new TRPCError({ + code: 'UNPROCESSABLE_CONTENT', + cause: input, + message: `Unexpected response: ${error.message}`, + }); }); return res; }),