Skip to content

Commit c21e58d

Browse files
lucaseduoliautofix-ci[bot]
authored andcommitted
fix: add reset db on command, expose error on e2e tests (#1627)
* fix factory reset not deleting data * make onboarding errors pop up on e2e tests * style: ruff format (auto) * added check for error when uploading * added check if its on first step to rollback, not only if its complete * reset correctly * update timeout for uploading document * remove misclick * fixed lint * fix mypy errors * style: ruff format (auto) --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 6f4053b commit c21e58d

6 files changed

Lines changed: 194 additions & 102 deletions

File tree

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ factory-reset: ## Complete reset (stop, remove volumes, clear data, remove image
534534
echo " - Remove all volumes"; \
535535
echo " - Delete langflow-data directory"; \
536536
echo " - Delete config directory"; \
537+
echo " - Delete data directory (database and session configs)"; \
537538
echo " - Delete JWT keys (private_key.pem, public_key.pem)"; \
538539
echo " - Remove OpenRAG images"; \
539540
echo ""; \
@@ -559,6 +560,16 @@ factory-reset: ## Complete reset (stop, remove volumes, clear data, remove image
559560
rm -rf config; \
560561
echo "$(PURPLE)config removed$(NC)"; \
561562
fi; \
563+
if [ -d "data" ]; then \
564+
echo "Removing data..."; \
565+
rm -rf data; \
566+
echo "$(PURPLE)data removed$(NC)"; \
567+
fi; \
568+
if [ -n "$$OPENRAG_DATA_PATH" ] && [ -d "$$OPENRAG_DATA_PATH" ]; then \
569+
echo "Removing $$OPENRAG_DATA_PATH..."; \
570+
rm -rf "$$OPENRAG_DATA_PATH"; \
571+
echo "$(PURPLE)$$OPENRAG_DATA_PATH removed$(NC)"; \
572+
fi; \
562573
if [ -f "keys/private_key.pem" ] || [ -f "keys/public_key.pem" ]; then \
563574
echo "Removing JWT keys..."; \
564575
rm -f keys/private_key.pem keys/public_key.pem 2>/dev/null || \

frontend/app/onboarding/_components/onboarding-card.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,10 @@ const OnboardingCard = ({
510510
>
511511
<div className="pb-6 flex items-center gap-4">
512512
<X className="w-4 h-4 text-destructive shrink-0" />
513-
<span className="text-mmd text-muted-foreground">
513+
<span
514+
data-testid="onboarding-error"
515+
className="text-mmd text-muted-foreground"
516+
>
514517
{error}
515518
</span>
516519
</div>

frontend/app/onboarding/_components/onboarding-upload.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => {
2424
const [uploadedTaskId, setUploadedTaskId] = useState<string | null>(null);
2525
const [shouldCreateFilter, setShouldCreateFilter] = useState(false);
2626
const [isCreatingFilter, setIsCreatingFilter] = useState(false);
27+
const [error, setError] = useState<string | null>(null);
2728

2829
const createFilterMutation = useCreateFilter();
2930
const updateOnboardingMutation = useUpdateOnboardingStateMutation();
@@ -63,6 +64,41 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => {
6364
matchingTask.status === "running" ||
6465
matchingTask.status === "processing";
6566

67+
// Check if matching task failed or has error status
68+
const failedTask =
69+
matchingTask.status === "failed" || matchingTask.status === "error";
70+
71+
// Check if any file inside the task failed
72+
const filesArray = matchingTask.files
73+
? (Object.values(matchingTask.files) as {
74+
status: string;
75+
error?: string;
76+
}[])
77+
: [];
78+
const hasFailedFile = filesArray.some(
79+
(file) => file.status === "failed" || file.status === "error",
80+
);
81+
82+
if (failedTask || hasFailedFile) {
83+
let errorMessage = "Document ingestion failed. Please try again.";
84+
if (matchingTask.error) {
85+
errorMessage = matchingTask.error;
86+
} else {
87+
const failedFile = filesArray.find(
88+
(file) =>
89+
(file.status === "failed" || file.status === "error") && file.error,
90+
);
91+
if (failedFile?.error) {
92+
errorMessage = failedFile.error;
93+
}
94+
}
95+
96+
setError(errorMessage);
97+
setCurrentStep(null);
98+
setUploadedTaskId(null);
99+
return;
100+
}
101+
66102
// If task is completed or has processed files, complete the onboarding step
67103
if (!isTaskActive || (matchingTask.processed_files ?? 0) > 0) {
68104
// Set to final step to show "Done"
@@ -169,6 +205,7 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => {
169205

170206
const performUpload = async (file: File) => {
171207
setIsUploading(true);
208+
setError(null);
172209
try {
173210
setCurrentStep(0);
174211
const result = await uploadFile(file, true, true); // Pass createFilter=true
@@ -193,6 +230,7 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => {
193230
const errorMessage =
194231
error instanceof Error ? error.message : "Upload failed";
195232
console.error("Upload failed", errorMessage);
233+
setError(errorMessage);
196234

197235
// Dispatch event that chat context can listen to
198236
// This avoids circular dependency issues
@@ -246,6 +284,25 @@ const OnboardingUpload = ({ onComplete }: OnboardingUploadProps) => {
246284
exit={{ opacity: 0, y: -24 }}
247285
transition={{ duration: 0.4, ease: "easeInOut" }}
248286
>
287+
<AnimatePresence mode="wait">
288+
{error && (
289+
<motion.div
290+
key="error"
291+
initial={{ opacity: 1, y: 0, height: "auto" }}
292+
exit={{ opacity: 0, y: -10, height: 0 }}
293+
>
294+
<div className="pb-6 flex items-center gap-4">
295+
<X className="w-4 h-4 text-destructive shrink-0" />
296+
<span
297+
data-testid="onboarding-upload-error"
298+
className="text-mmd text-muted-foreground"
299+
>
300+
{error}
301+
</span>
302+
</div>
303+
</motion.div>
304+
)}
305+
</AnimatePresence>
249306
<Button
250307
size="sm"
251308
variant="outline"

frontend/tests/utils/onboarding.ts

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,19 @@ export async function completeOnboarding(
5454
}
5555

5656
const isCompleted = await completedLocator.isVisible();
57+
const isFirstStep = await page.getByTestId("openai-llm-tab").isVisible();
5758

58-
if (isCompleted) {
59-
if (!reset) {
60-
console.log("Onboarding already complete, skipping...");
61-
return;
62-
}
59+
if (isCompleted && !reset) {
60+
console.log("Onboarding already complete, skipping...");
61+
return;
62+
}
63+
64+
const needsRollback = reset && (isCompleted || !isFirstStep);
6365

64-
console.log("Onboarding complete and reset is true, rolling back...");
66+
if (needsRollback) {
67+
console.log(
68+
"Onboarding complete or not on the first step, and reset is true, rolling back...",
69+
);
6570
const response = await page.request.post("/api/onboarding/rollback");
6671
if (!response.ok()) {
6772
const text = await response.text();
@@ -141,9 +146,18 @@ export async function completeOnboarding(
141146
await page.getByTestId("onboarding-complete-button").click();
142147

143148
await expect(page.getByText("Thinking")).toBeVisible();
144-
await expect(page.getByText("Done")).toBeVisible({
149+
150+
const doneLocator = page.getByText("Done");
151+
const errorLocator = page.getByTestId("onboarding-error");
152+
153+
await expect(doneLocator.or(errorLocator)).toBeVisible({
145154
timeout: isEmbedding ? 120000 : 60000,
146155
});
156+
157+
if (await errorLocator.isVisible()) {
158+
const errorText = await errorLocator.innerText();
159+
throw new Error(`Onboarding step failed: ${errorText}`);
160+
}
147161
};
148162

149163
// 1. LLM configuration
@@ -182,6 +196,17 @@ export async function completeOnboarding(
182196
path.join(__dirname, "../assets", "test-document.md"),
183197
);
184198

185-
await expect(page.getByText("Done")).toBeVisible({ timeout: 60000 });
199+
const uploadDoneLocator = page.getByText("Done");
200+
const uploadErrorLocator = page.getByTestId("onboarding-upload-error");
201+
202+
await expect(uploadDoneLocator.or(uploadErrorLocator)).toBeVisible({
203+
timeout: 120000,
204+
});
205+
206+
if (await uploadErrorLocator.isVisible()) {
207+
const errorText = await uploadErrorLocator.innerText();
208+
throw new Error(`Onboarding document upload failed: ${errorText}`);
209+
}
210+
186211
await expect(page.getByTestId("onboarding-content")).toBeHidden();
187212
}

src/api/settings/endpoints.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,10 @@ async def remove_filter(filter_id: str | None):
13731373
current_config.knowledge.embedding_model = ""
13741374
current_config.onboarding.openrag_docs_ingested_version = None
13751375
current_config.onboarding.openrag_docs_remote_signature = None
1376+
current_config.onboarding.assistant_message = None
1377+
current_config.onboarding.selected_nudge = None
1378+
current_config.onboarding.card_steps = None
1379+
current_config.onboarding.upload_steps = None
13761380

13771381
embedding_only = body.embedding_only if body else False
13781382

0 commit comments

Comments
 (0)