Unknown error: {errMsg}
), ) - .with(P.shape({ runner_pool_error: P.shape({ runner_id: P.string }) }), (err) => ( -- Runner ({err.runner_no_response.runner_id}) was allocated but Actor - did not respond. -
- )) - .with(P.shape({ runner_connection_lost: P.shape({ runner_id: P.string }) }), (err) => ( -- Runner ({err.runner_connection_lost.runner_id}) connection was lost - (no recent ping, network issue, or crash). -
- )) - .with(P.shape({ runner_draining_timeout: P.shape({ runner_id: P.string }) }), (err) => ( -- Runner ({err.runner_draining_timeout.runner_id}) was draining but - Actor didn't stop in time. -
- )) + .with( + P.shape({ + runner_pool_error: P.shape({ runner_id: P.string }) + .or(P.shape({ serverless_http_error: P.any })) + .or(P.string) + .or(P.shape({ serverless_connection_error: P.any })) + .or(P.shape({ serverless_invalid_sse_payload: P.any })), + }), + (err) =>+ Runner ({err.runner_no_response.runner_id}) was allocated + but Actor did not respond. +
+ ), + ) + .with( + P.shape({ + runner_connection_lost: P.shape({ runner_id: P.string }), + }), + (err) => ( ++ Runner ({err.runner_connection_lost.runner_id}) connection + was lost (no recent ping, network issue, or crash). +
+ ), + ) + .with( + P.shape({ + runner_draining_timeout: P.shape({ runner_id: P.string }), + }), + (err) => ( ++ Runner ({err.runner_draining_timeout.runner_id}) was + draining but Actor didn't stop in time. +
+ ), + ) .with(P.shape({ crashed: P.shape({ message: P.string }) }), (err) => (Actor crashed. {err.crashed.message}
)) @@ -139,7 +159,13 @@ export function QueriedActorError({ actorId }: { actorId: ActorId }) { export function RunnerPoolError({ error, }: { - error: object | string | undefined; + error: + | string + | null + | { runner_id: string } + | { serverless_http_error: unknown } + | { serverless_connection_error: unknown } + | { serverless_invalid_sse_payload: unknown }; }) { return match(error) .with(P.nullish, () => null) @@ -153,34 +179,52 @@ export function RunnerPoolError({ )) .otherwise(() =>Unknown runner pool error
), ) - .with(P.shape({ serverless_http_error: P.shape({ status_code: P.number, body: P.string }) }), (errObj) => { - const { status_code, body } = errObj.serverless_http_error; - const code = status_code ?? "unknown"; - return ( - <> -Serverless HTTP error with status code {code}
- {body ?Unable to connect to serverless endpoint
- {message ?Request payload validation failed
- {message ?Serverless HTTP error with status code {code}
+ {body ?Unable to connect to serverless endpoint
+ {message ?Request payload validation failed
+ {message ?Unknown runner pool error.
; }); diff --git a/frontend/src/components/actors/dialogs/create-actor-dialog.tsx b/frontend/src/components/actors/dialogs/create-actor-dialog.tsx index 8d5a8dea3c..5f15cdb810 100644 --- a/frontend/src/components/actors/dialogs/create-actor-dialog.tsx +++ b/frontend/src/components/actors/dialogs/create-actor-dialog.tsx @@ -41,7 +41,9 @@ export default function CreateActorDialog({ onClose }: ContentProps) { input: values.input ? JSON.parse(values.input) : undefined, key: values.key, datacenter: - __APP_TYPE__ === "inspector" ? "" : values.datacenter, + __APP_TYPE__ === "inspector" + ? undefined + : values.datacenter, crashPolicy: values.crashPolicy || Rivet.CrashPolicy.Sleep, runnerNameSelector: values.runnerNameSelector || "default", }); diff --git a/frontend/src/queries/global.ts b/frontend/src/queries/global.ts index 7a9a1845e7..677410bdf3 100644 --- a/frontend/src/queries/global.ts +++ b/frontend/src/queries/global.ts @@ -11,6 +11,8 @@ import { isRivetApiError } from "@/lib/errors"; import { modal } from "@/utils/modal-utils"; import { Changelog } from "./types"; +const previousQueryCache = new QueryCache(); + const queryCache = new QueryCache({ onError(error, query) { // Silently ignore CancelledError - these are expected during navigation/unmount @@ -34,12 +36,19 @@ const queryCache = new QueryCache({ queryKey: query.queryKey, }); } + + if (query.meta?.statusCheck) { + previousQueryCache.remove(query); + } }, onSuccess(data, query) { if (query.meta?.statusCheck) { - queryClient.invalidateQueries({ - predicate: (q) => q.state.error !== null, - }); + if (!previousQueryCache.find(query)) { + previousQueryCache.add(query); + queryClient.invalidateQueries({ + predicate: (q) => q.state.error !== null, + }); + } } }, }); diff --git a/frontend/src/routes/_context/_cloud/orgs.$organization/projects.$project/ns.$namespace/index.tsx b/frontend/src/routes/_context/_cloud/orgs.$organization/projects.$project/ns.$namespace/index.tsx index 6373e586b9..210e415332 100644 --- a/frontend/src/routes/_context/_cloud/orgs.$organization/projects.$project/ns.$namespace/index.tsx +++ b/frontend/src/routes/_context/_cloud/orgs.$organization/projects.$project/ns.$namespace/index.tsx @@ -5,7 +5,7 @@ import { } from "@tanstack/react-router"; import { Actors } from "@/app/actors"; import { BuildPrefiller } from "@/app/build-prefiller"; -import { PendingRouteLayout } from "@/app/route-layout"; +import { FullscreenLoading } from "@/components"; export const Route = createFileRoute( "/_context/_cloud/orgs/$organization/projects/$project/ns/$namespace/", @@ -16,7 +16,7 @@ export const Route = createFileRoute( throw notFound(); } }, - pendingComponent: PendingRouteLayout, + pendingComponent: FullscreenLoading, }); export function RouteComponent() {