Skip to content

Commit 4748310

Browse files
skeptrunedevcdxker
authored andcommitted
feat: implement retry logic for operations and enhance error handling in suggested queries
1 parent 3fb1b7b commit 4748310

File tree

4 files changed

+329
-198
lines changed

4 files changed

+329
-198
lines changed

clients/search-component/src/TrieveModal/FilterSidebarComponents.tsx

Lines changed: 144 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
import { toBase64 } from "./Search/UploadImage";
1717
import { getPresignedUrl, uploadFile } from "../utils/trieve";
1818
import { ModalContainer } from "./ModalContainer";
19-
import { useChatState } from "../utils/hooks/chat-context";
19+
import { retryOperation, useChatState } from "../utils/hooks/chat-context";
2020
import convert from "heic-convert/browser";
2121

2222
export const ActiveFilterPills = () => {
@@ -380,23 +380,51 @@ export const InferenceFiltersForm = ({ steps }: InferenceFiltersFormProps) => {
380380
promptDescription += `\n\n[User's goal for the space (take more into account than anything else)]:\n${prevInputText}`;
381381
}
382382

383-
const replacementMaterialDescriptionReader =
384-
await trieveSDK.ragOnChunkReader(
385-
{
386-
chunk_ids: [],
387-
image_urls: Object.values(imageUrls).filter((url) => url),
388-
prev_messages: [
383+
let retries = 0;
384+
let replacementMaterialDescriptionReader = null;
385+
while (!replacementMaterialDescriptionReader) {
386+
try {
387+
const firstMessageInferenceAbortController =
388+
new AbortController();
389+
const timeoutId = setTimeout(() => {
390+
firstMessageInferenceAbortController.abort(
391+
"Timeout after 10 seconds",
392+
);
393+
}, 10000);
394+
395+
replacementMaterialDescriptionReader =
396+
await trieveSDK.ragOnChunkReader(
389397
{
390-
content: promptDescription,
391-
role: "user",
398+
chunk_ids: [],
399+
image_urls: Object.values(imageUrls).filter((url) => url),
400+
prev_messages: [
401+
{
402+
content: promptDescription,
403+
role: "user",
404+
},
405+
],
406+
prompt: "",
407+
stream_response: true,
408+
user_id: fingerprint.toString(),
392409
},
393-
],
394-
prompt: "",
395-
stream_response: true,
396-
user_id: fingerprint.toString(),
397-
},
398-
firstMessageInferenceAbortController.signal,
399-
);
410+
firstMessageInferenceAbortController.signal,
411+
);
412+
413+
clearTimeout(timeoutId);
414+
break;
415+
} catch (error) {
416+
retries++;
417+
console.error(`Attempt ${retries} failed:`, error);
418+
419+
if (retries >= 3) {
420+
console.error("Max retries reached, giving up");
421+
throw error;
422+
}
423+
424+
await new Promise((resolve) => setTimeout(resolve, 500));
425+
}
426+
}
427+
400428
setLoadingStates((prev) => ({
401429
...prev,
402430
[steps[i].title]: "Generating search query...",
@@ -457,23 +485,50 @@ export const InferenceFiltersForm = ({ steps }: InferenceFiltersFormProps) => {
457485
[steps[i].title]: "Understanding your space...",
458486
}));
459487

460-
const replacementMaterialDescriptionReader =
461-
await trieveSDK.ragOnChunkReader(
462-
{
463-
chunk_ids: [],
464-
image_urls: Object.values(imageUrls).filter((url) => url),
465-
prev_messages: [
488+
let retries = 0;
489+
let replacementMaterialDescriptionReader = null;
490+
while (!replacementMaterialDescriptionReader) {
491+
try {
492+
const firstMessageInferenceAbortController =
493+
new AbortController();
494+
const timeoutId = setTimeout(() => {
495+
firstMessageInferenceAbortController.abort(
496+
"Timeout after 10 seconds",
497+
);
498+
}, 10000);
499+
500+
replacementMaterialDescriptionReader =
501+
await trieveSDK.ragOnChunkReader(
466502
{
467-
content: `${steps[i].prompt ?? ""}`,
468-
role: "user",
503+
chunk_ids: [],
504+
image_urls: Object.values(imageUrls).filter((url) => url),
505+
prev_messages: [
506+
{
507+
content: `${steps[i].prompt ?? ""}`,
508+
role: "user",
509+
},
510+
],
511+
prompt: "",
512+
stream_response: true,
513+
user_id: fingerprint.toString(),
469514
},
470-
],
471-
prompt: "",
472-
stream_response: true,
473-
user_id: fingerprint.toString(),
474-
},
475-
textInferenceAbortController.signal,
476-
);
515+
textInferenceAbortController.signal,
516+
);
517+
518+
clearTimeout(timeoutId);
519+
break;
520+
} catch (error) {
521+
retries++;
522+
console.error(`Attempt ${retries} failed:`, error);
523+
524+
if (retries >= 3) {
525+
console.error("Max retries reached, giving up");
526+
throw error;
527+
}
528+
529+
await new Promise((resolve) => setTimeout(resolve, 500));
530+
}
531+
}
477532

478533
setLoadingStates((prev) => ({
479534
...prev,
@@ -626,33 +681,36 @@ export const InferenceFiltersForm = ({ steps }: InferenceFiltersFormProps) => {
626681
...prev,
627682
[step.title]: "Uploading image...",
628683
}));
629-
toBase64(processedFile).then((data) => {
630-
const base64File = data
631-
.split(",")[1]
632-
.replace(/\+/g, "-")
633-
.replace(/\//g, "_")
634-
.replace(/=+$/, "");
635-
uploadFile(trieveSDK, processedFile.name, base64File).then(
636-
(fileId) => {
637-
getPresignedUrl(trieveSDK, fileId).then((imageUrl) => {
638-
setImageUrls((prev) => ({
639-
...prev,
640-
[step.title]: imageUrl,
641-
}));
642-
643-
setLoadingStates((prev) => ({
644-
...prev,
645-
[step.title]: "idle",
646-
}));
684+
retryOperation(() => toBase64(processedFile))
685+
.then(async (data) => {
686+
const base64File = data
687+
.split(",")[1]
688+
.replace(/\+/g, "-")
689+
.replace(/\//g, "_")
690+
.replace(/=+$/, "");
647691

648-
setCompletedSteps((prev) => ({
649-
...prev,
650-
[step.title]: true,
651-
}));
652-
});
653-
},
654-
);
655-
});
692+
const fileId = await retryOperation(() =>
693+
uploadFile(trieveSDK, processedFile.name, base64File),
694+
);
695+
const imageUrl = await retryOperation(() =>
696+
getPresignedUrl(trieveSDK, fileId),
697+
);
698+
setImageUrls((prev) => ({
699+
...prev,
700+
[step.title]: imageUrl,
701+
}));
702+
setLoadingStates((prev) => ({
703+
...prev,
704+
[step.title]: "idle",
705+
}));
706+
setCompletedSteps((prev) => ({
707+
...prev,
708+
[step.title]: true,
709+
}));
710+
})
711+
.catch((error) => {
712+
console.error("Operation failed after retries:", error);
713+
});
656714
}}
657715
onClick={() => {
658716
const input = document.createElement("input");
@@ -727,33 +785,36 @@ export const InferenceFiltersForm = ({ steps }: InferenceFiltersFormProps) => {
727785
...prev,
728786
[step.title]: "Uploading image...",
729787
}));
730-
toBase64(processedFile).then((data) => {
731-
const base64File = data
732-
.split(",")[1]
733-
.replace(/\+/g, "-")
734-
.replace(/\//g, "_")
735-
.replace(/=+$/, "");
736-
uploadFile(trieveSDK, processedFile.name, base64File).then(
737-
(fileId) => {
738-
getPresignedUrl(trieveSDK, fileId).then((imageUrl) => {
739-
setImageUrls((prev) => ({
740-
...prev,
741-
[step.title]: imageUrl,
742-
}));
743-
744-
setLoadingStates((prev) => ({
745-
...prev,
746-
[step.title]: "idle",
747-
}));
788+
retryOperation(() => toBase64(processedFile))
789+
.then(async (data) => {
790+
const base64File = data
791+
.split(",")[1]
792+
.replace(/\+/g, "-")
793+
.replace(/\//g, "_")
794+
.replace(/=+$/, "");
748795

749-
setCompletedSteps((prev) => ({
750-
...prev,
751-
[step.title]: true,
752-
}));
753-
});
754-
},
755-
);
756-
});
796+
const fileId = await retryOperation(() =>
797+
uploadFile(trieveSDK, processedFile.name, base64File),
798+
);
799+
const imageUrl = await retryOperation(() =>
800+
getPresignedUrl(trieveSDK, fileId),
801+
);
802+
setImageUrls((prev) => ({
803+
...prev,
804+
[step.title]: imageUrl,
805+
}));
806+
setLoadingStates((prev) => ({
807+
...prev,
808+
[step.title]: "idle",
809+
}));
810+
setCompletedSteps((prev) => ({
811+
...prev,
812+
[step.title]: true,
813+
}));
814+
})
815+
.catch((error) => {
816+
console.error("Operation failed after retries:", error);
817+
});
757818
};
758819

759820
input.click();

clients/search-component/src/TrieveModal/Search/SuggestedQueries.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export const SuggestedQueries = () => {
1919
query,
2020
count: props.numberOfSuggestions ?? 3,
2121
abortController,
22-
}).then((queries) => {
23-
setSuggestedQueries(queries.queries);
22+
}).then((suggestedQueriesResp) => {
23+
setSuggestedQueries(suggestedQueriesResp.queries);
2424
setIsLoading(false);
2525
});
2626
},

0 commit comments

Comments
 (0)