Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle PydanticSerializationError that generates generic errors in the UI #3108

Merged
merged 9 commits into from
Jul 31, 2024
17 changes: 11 additions & 6 deletions src/backend/base/langflow/main.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import os
import asyncio
import json
import os
import warnings
from contextlib import asynccontextmanager
from http import HTTPStatus
from pathlib import Path
from typing import Optional
from urllib.parse import urlencode

import nest_asyncio # type: ignore
from fastapi import FastAPI, Request, Response, HTTPException
from fastapi import FastAPI, HTTPException, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from http import HTTPStatus
from loguru import logger
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from pydantic import PydanticDeprecatedSince20
from pydantic_core import PydanticSerializationError
from rich import print as rprint
from starlette.middleware.base import BaseHTTPMiddleware
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor

from langflow.api import router, health_check_router, log_router
from langflow.api import health_check_router, log_router, router
from langflow.initial_setup.setup import (
create_or_update_starter_projects,
initialize_super_user_if_needed,
Expand Down Expand Up @@ -67,7 +69,10 @@ async def dispatch(self, request: Request, call_next):
try:
response = await call_next(request)
except Exception as exc:
logger.error(exc)
if isinstance(exc, PydanticSerializationError):
message = "Something went wrong while serializing the response. Please share this error on our GitHub repository."
error_messages = json.dumps([message, str(exc)])
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_messages) from exc
raise exc
if "files/" not in request.url.path and request.url.path.endswith(".js") and response.status_code == 200:
response.headers["Content-Type"] = "text/javascript"
Expand Down
14 changes: 10 additions & 4 deletions src/frontend/src/utils/buildUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import useFlowStore from "../stores/flowStore";
import { VertexBuildTypeAPI } from "../types/api";
import { isErrorLogType } from "../types/utils/typeCheckingUtils";
import { VertexLayerElementType } from "../types/zustand/flow";
import { tryParseJson } from "./utils";

type BuildVerticesParams = {
setLockChat?: (lock: boolean) => void;
Expand Down Expand Up @@ -306,12 +307,17 @@ async function buildVertex({
buildResults.push(buildData.valid);
} catch (error) {
console.error(error);
let errorMessage: string | string[] =
(error as AxiosError<any>).response?.data?.detail ||
(error as AxiosError<any>).response?.data?.message ||
"An unexpected error occurred while building the Component. Please try again.";
errorMessage = tryParseJson(errorMessage as string) ?? errorMessage;
if (!Array.isArray(errorMessage)) {
errorMessage = [errorMessage];
}
onBuildError!(
"Error Building Component",
[
(error as AxiosError<any>).response?.data?.detail ??
"An unexpected error occurred while building the Component. Please try again.",
],
errorMessage,
verticesIds.map((id) => ({ id })),
);
buildResults.push(false);
Expand Down
16 changes: 16 additions & 0 deletions src/frontend/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,3 +546,19 @@ export function generateBackendColumnsFromValue(rows: Object[]): ColumnField[] {
return newColumn;
});
}

/**
* Tries to parse a JSON string and returns the parsed object.
* If parsing fails, returns undefined.
*
* @param json - The JSON string to parse.
* @returns The parsed JSON object, or undefined if parsing fails.
*/
export function tryParseJson(json: string) {
try {
const parsedJson = JSON.parse(json);
return parsedJson;
} catch (error) {
return;
}
}
Loading