Skip to content

Commit

Permalink
fix: handle PydanticSerializationError that generates generic errors …
Browse files Browse the repository at this point in the history
…in the UI (langflow-ai#3108)

* fix(main.py): handle PydanticSerializationError in JavaScriptMIMETypeMiddleware to provide detailed error message in case of serialization error

* fix(main.py): handle PydanticSerializationError in JavaScriptMIMETypeMiddleware to provide detailed error message in case of serialization error

* improve error handling

* feat: Handle PydanticSerializationError in JavaScriptMIMETypeMiddleware

Refactor the `JavaScriptMIMETypeMiddleware` class in `main.py` to handle the `PydanticSerializationError` exception. This change ensures that a detailed error message is provided in case of a serialization error. The error message is now serialized as a JSON string and included in the `detail` field of the `HTTPException` raised.

* feat: Add tryParseJson function to utils.ts

This commit adds a new function called `tryParseJson` to the `utils.ts` file. The function attempts to parse a JSON string and returns the parsed object. If parsing fails, it returns undefined. This function can be used to safely parse JSON strings without throwing an error.

* fix: Handle error message in buildVertex function

This commit modifies the buildVertex function in buildUtils.ts to handle error messages more effectively. It adds logic to extract the error message from the AxiosError response and parse it as JSON if possible. If the error message is not an array, it converts it into an array. This change ensures that the error message is properly displayed when building a component fails.

* remove console.log

* remove not related code

---------

Co-authored-by: anovazzi1 <[email protected]>
(cherry picked from commit f08467d)
  • Loading branch information
ogabrielluiz authored and nicoloboschi committed Aug 1, 2024
1 parent cc2cc60 commit 4c34a1e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
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;
}
}

0 comments on commit 4c34a1e

Please sign in to comment.