Skip to content

Commit f69b024

Browse files
committed
wip: improved panel timeout error handling + small stuff
1 parent 15c1769 commit f69b024

5 files changed

Lines changed: 40 additions & 36 deletions

File tree

core/modules/AdminStore/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ export default class AdminStore {
350350
* Add a new admin to the admins file
351351
* NOTE: I'm fully aware this coud be optimized. Leaving this way to improve readability and error verbosity
352352
* @param {string} name
353-
* @param {object|undefined} citizenfxData or false
354-
* @param {object|undefined} discordData or false
353+
* @param {object|false} citizenfxData or false
354+
* @param {object|false} discordData or false
355355
* @param {string} password
356356
* @param {array} permissions
357357
*/

panel/src/hooks/fetch.ts

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { txToast, validToastTypes } from "@/components/TxToaster";
22
import { useCsrfToken, useExpireAuthData } from "@/hooks/auth";
3+
import { msToShortDuration } from "@/lib/dateTime";
34
import { useEffect, useRef } from "react";
45

56
const WEBPIPE_PATH = "https://monitor/WebPipe";
@@ -131,6 +132,9 @@ type ApiCallOpts<RespType, ReqType> = {
131132
finally?: () => void;
132133
}
133134

135+
//Just syntax sugar
136+
const VOID = undefined as void;
137+
134138
export const useBackendApi = <
135139
RespType = any,
136140
ReqType = NonNullable<Object>,
@@ -149,6 +153,9 @@ export const useBackendApi = <
149153
}
150154
}, []);
151155

156+
/**
157+
* @returns VOID if the request was aborted or error was handled, otherwise the response data
158+
*/
152159
return async (opts: ApiCallOpts<RespType, ReqType>) => {
153160
//The abort controller is not aborted, just forgotten
154161
abortController.current = new AbortController();
@@ -205,12 +212,14 @@ export const useBackendApi = <
205212
}
206213

207214
//Starting request timeout
215+
const timeoutMs = opts.timeout ?? ApiTimeout.DEFAULT;
208216
const timeoutId = setTimeout(() => {
209217
if (abortController.current?.signal.aborted) return;
210218
console.log('[TIMEOUT]', apiCallDesc);
211-
abortController.current?.abort('timeout');
219+
const msg = `Request timed out after ${msToShortDuration(timeoutMs, {units: ['s', 'ms']})}.`;
220+
abortController.current?.abort(msg);
212221
handleError('Request Timeout', 'If you closed txAdmin, please restart it and try again.');
213-
}, opts.timeout ?? ApiTimeout.DEFAULT);
222+
}, timeoutMs);
214223

215224
try {
216225
//Make request
@@ -220,7 +229,9 @@ export const useBackendApi = <
220229
body: opts.data,
221230
}, abortController.current);
222231
clearTimeout(timeoutId);
223-
if (abortController.current?.signal.aborted) return;
232+
// if (abortController.current?.signal.aborted) {
233+
// throw abortController.current.signal.reason;
234+
// };
224235

225236
//If generic error
226237
if (hookOpts.throwGenericErrors && 'error' in data) {
@@ -261,11 +272,22 @@ export const useBackendApi = <
261272
return data as RespType;
262273

263274
} catch (e) {
264-
if (abortController.current?.signal.aborted) return;
275+
// console.warn('Error Handling:', {
276+
// aborted: abortController.current?.signal.aborted,
277+
// reason: abortController.current?.signal.reason,
278+
// typeof: typeof e,
279+
// e,
280+
// });
265281
clearTimeout(timeoutId);
282+
if (e === 'unmount') {
283+
console.warn('[UNMOUNTED]', apiCallDesc);
284+
return VOID;
285+
}
286+
const error = abortController.current?.signal.reason ?? e as any;
266287
let errorMessage = 'unknown error';
267-
const error = e as any;
268-
if (typeof error.message !== 'string') {
288+
if(typeof error === 'string') {
289+
errorMessage = error;
290+
} else if (typeof error.message !== 'string') {
269291
errorMessage = JSON.stringify(error);
270292
} else if (error.message.startsWith('NetworkError')) {
271293
errorMessage = 'Network error.\nIf you closed txAdmin, please restart it and try again.';
@@ -274,13 +296,10 @@ export const useBackendApi = <
274296
} else {
275297
errorMessage = error.message;
276298
}
277-
278-
if (errorMessage.includes('unmount')) {
279-
console.warn('[UNMOUNTED]', apiCallDesc);
280-
} else {
281-
console.error('[ERROR]', apiCallDesc, errorMessage);
282-
handleError('Request Error', errorMessage);
283-
}
299+
300+
console.error('[ERROR]', apiCallDesc, errorMessage);
301+
handleError('Request Error', errorMessage);
302+
return VOID;
284303
} finally {
285304
if (opts.finally) {
286305
try {

panel/src/pages/Dashboard/DashboardPage.tsx

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,6 @@ function DashboardPageInner() {
4747
<ThreadPerfCard />
4848
</div>
4949
<FullPerfCard />
50-
51-
{/* TODO: maybe convert in top server warning */}
52-
{/* <div className="mx-auto max-w-4xl w-full sm:w-auto sm:min-w-[28rem] relative overflow-hidden z-40 p-3 pr-10 flex items-center justify-between space-x-4 rounded-xl border shadow-lg transition-all text-black/75 dark:text-white/90 border-warning/70 bg-warning-hint animate-toastbar-enter opacity-50 hover:opacity-100">
53-
<div className="flex-shrink-0 flex flex-col gap-2 items-center">
54-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-warning stroke-warning animate-toastbar-icon">
55-
<circle cx="12" cy="12" r="10"></circle>
56-
<path d="M12 16v-4"></path>
57-
<path d="M12 8h.01"></path>
58-
</svg>
59-
</div>
60-
<div className="flex-grow">
61-
<span className="block whitespace-pre-line">
62-
<b>This update changes how the performance chart show its data.</b> <br />
63-
Now the histogram (colors) are based on the time spent on each bucket instead of the number of ticks. And the bucket boundaries (ms) may have changed to have a better resolution at lower tick times.
64-
</span>
65-
</div>
66-
</div> */}
6750
</div>
6851
);
6952
}
@@ -82,7 +65,7 @@ export default function DashboardPage() {
8265
} else if (txConfigState !== TxConfigState.Ready) {
8366
return <div className='size-full'>
8467
<ModalTabMessage>
85-
<GenericSpinner msg={`Unknown Config State: ${String(txConfigState)}`} />
68+
<GenericSpinner msg={`Unknown Config State: ${String(txConfigState)}`} />
8669
</ModalTabMessage>
8770
</div>;
8871
} else {

resource/sv_main.lua

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,14 @@ end
281281

282282
-- Event so the client can ack the warning
283283
RegisterNetEvent('txsv:ackWarning', function(actionId)
284-
if pendingWarnings[tostring(source)] == actionId then
284+
if type(actionId) ~= 'string' then return end
285+
local srcStr = tostring(source)
286+
if pendingWarnings[srcStr] == actionId then
285287
PrintStructuredTrace(json.encode({
286288
type = 'txAdminAckWarning',
287289
actionId = actionId,
288290
}))
289-
pendingWarnings[tostring(source)] = nil
291+
pendingWarnings[srcStr] = nil
290292
end
291293
end)
292294

scripts/build/dev.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fs.writeFileSync(path.join(fxsPaths.monitor, 'package.json'), '{"type":"commonjs
5757
//Create txAdmin process runner
5858
const txInstance = new TxAdminRunner(fxsPaths.root, fxsPaths.bin, txDevEnv);
5959

60-
//Listens on stdin for the key 'r'
60+
//Listens on stdin for commands
6161
process.stdin.on('data', (data) => {
6262
const cmd = data.toString().toLowerCase().trim();
6363
if (cmd === 'r' || cmd === 'rr') {

0 commit comments

Comments
 (0)