Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion apps/dashboard/src/@/hooks/useEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,27 @@ export function useEngineTransactions(params: {
page?: number;
status?: EngineStatus;
};
id?: string;
}) {
const { instanceUrl, autoUpdate, authToken } = params;
const { instanceUrl, autoUpdate, authToken, id } = params;

return useQuery({
placeholderData: keepPreviousData,
queryFn: async () => {
if (id) {
const res = await fetch(`${instanceUrl}transaction/${id}`, {
headers: getEngineRequestHeaders(authToken),
method: "GET",
});

const json = await res.json();
const transaction = (json.result as Transaction) || {};
return {
transactions: [transaction],
totalCount: 1,
};
}
Comment on lines +389 to +401
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add error handling and response validation.

The single-transaction fetch path lacks error handling and response validation. Consider these concerns:

  1. No HTTP status check - non-2xx responses are not handled
  2. No validation that json.result exists before casting
  3. Empty object fallback (|| {}) could return invalid Transaction shape

While the existing fetch-all path (lines 414-421) has similar patterns, this represents a good opportunity to add defensive checks.

Consider this approach:

 if (id) {
   const res = await fetch(`${instanceUrl}transaction/${id}`, {
     headers: getEngineRequestHeaders(authToken),
     method: "GET",
   });

+  if (!res.ok) {
+    throw new Error(`Failed to fetch transaction: ${res.status} ${await res.text()}`);
+  }
+
   const json = await res.json();
-  const transaction = (json.result as Transaction) || {};
+  
+  if (!json.result) {
+    throw new Error("Invalid response: missing result field");
+  }
+  
+  const transaction = json.result as Transaction;
   return {
     transactions: [transaction],
     totalCount: 1,
   };
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (id) {
const res = await fetch(`${instanceUrl}transaction/${id}`, {
headers: getEngineRequestHeaders(authToken),
method: "GET",
});
const json = await res.json();
const transaction = (json.result as Transaction) || {};
return {
transactions: [transaction],
totalCount: 1,
};
}
if (id) {
const res = await fetch(`${instanceUrl}transaction/${id}`, {
headers: getEngineRequestHeaders(authToken),
method: "GET",
});
if (!res.ok) {
throw new Error(`Failed to fetch transaction: ${res.status} ${await res.text()}`);
}
const json = await res.json();
if (!json.result) {
throw new Error("Invalid response: missing result field");
}
const transaction = json.result as Transaction;
return {
transactions: [transaction],
totalCount: 1,
};
}
🤖 Prompt for AI Agents
In apps/dashboard/src/@/hooks/useEngine.ts around lines 389 to 401, the
single-transaction fetch path lacks HTTP status checking and response
validation; add a res.ok check and throw or handle non-2xx responses, parse json
and verify json.result exists and has the expected Transaction shape (at least
required fields like id), avoid using a blind || {} fallback, and return either
a validated transactions array with totalCount 1 or an empty array with
totalCount 0 (or propagate the error) — wrap the fetch in try/catch to surface
or log errors consistently with the fetch-all path and ensure the function
always returns the same response shape.


const url = new URL(`${instanceUrl}transaction/get-all`);
if (params.queryParams) {
for (const key in params.queryParams) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Input } from "@workspace/ui/components/input";
import { format, formatDistanceToNowStrict } from "date-fns";
import {
ArrowLeftIcon,
Expand Down Expand Up @@ -110,6 +111,7 @@ export function TransactionsTable(props: {
const [autoUpdate, setAutoUpdate] = useState(true);
const [page, setPage] = useState(1);
const [status, setStatus] = useState<EngineStatus | undefined>(undefined);
const [filterId, setFilterId] = useState<string | undefined>(undefined);
const autoUpdateId = useId();
const pageSize = 10;
const transactionsQuery = useEngineTransactions({
Expand All @@ -121,6 +123,7 @@ export function TransactionsTable(props: {
page: page,
status,
},
id: filterId,
});

const transactions = transactionsQuery.data?.transactions ?? [];
Expand Down Expand Up @@ -160,6 +163,16 @@ export function TransactionsTable(props: {
onCheckedChange={(v) => setAutoUpdate(!!v)}
/>
</div>
<Input
className="max-w-[250px]"
onChange={(e) => {
const value = e.target.value.trim();
setFilterId(value || undefined);
setPage(1);
}}
placeholder="Filter by Queue ID"
value={filterId || ""}
/>
<StatusSelector
setStatus={(v) => {
setStatus(v);
Expand Down
Loading