error handling with hard reset

This commit is contained in:
anovazzi1 2023-03-24 19:40:25 -03:00
commit 5f7be7d1a5
9 changed files with 163 additions and 71 deletions

View file

@ -26,6 +26,7 @@
"react": "^18.2.0",
"react-cookie": "^4.1.1",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.2",
"react-icons": "^4.7.1",
"react-laag": "^2.0.5",
"react-router-dom": "^6.8.1",
@ -14960,6 +14961,17 @@
"react": "^18.2.0"
}
},
"node_modules/react-error-boundary": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.2.tgz",
"integrity": "sha512-/h21OS80hQ1m/s5UVOp1JKkC8XmUo0rOTRUliGSmWtvswkbbijuQ074K0QLEHwxwwesTt7ksR74/9EHImqWo+A==",
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"peerDependencies": {
"react": ">=16.13.1"
}
},
"node_modules/react-error-overlay": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",

View file

@ -21,6 +21,7 @@
"react": "^18.2.0",
"react-cookie": "^4.1.1",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.2",
"react-icons": "^4.7.1",
"react-laag": "^2.0.5",
"react-router-dom": "^6.8.1",

View file

@ -9,6 +9,9 @@ import ExtraSidebar from "./components/ExtraSidebarComponent";
import { alertContext } from "./contexts/alertContext";
import { locationContext } from "./contexts/locationContext";
import TabsManagerComponent from "./pages/FlowPage/components/tabsManagerComponent";
import { ErrorBoundary } from "react-error-boundary";
import CrashErrorComponent from "./components/CrashErrorComponent";
import { TabsContext } from "./contexts/tabsContext";
export default function App() {
var _ = require("lodash");
@ -21,7 +24,7 @@ export default function App() {
setShowSideBar(true);
setIsStackedOpen(true);
}, [location.pathname, setCurrent, setIsStackedOpen, setShowSideBar]);
const {hardReset} = useContext(TabsContext)
const {
errorData,
errorOpen,
@ -34,45 +37,62 @@ export default function App() {
setSuccessOpen,
} = useContext(alertContext);
// Initialize state variable for the list of alerts
const [alertsList, setAlertsList] = useState<Array<{type:string,data:{title:string,list?:Array<string>,link?:string},id:string}>>([]);
// Initialize state variable for the list of alerts
const [alertsList, setAlertsList] = useState<
Array<{
type: string;
data: { title: string; list?: Array<string>; link?: string };
id: string;
}>
>([]);
// Use effect hook to update alertsList when a new alert is added
useEffect(() => {
// If there is an error alert open with data, add it to the alertsList
if (errorOpen && errorData) {
setErrorOpen(false);
setAlertsList((old) => {
let newAlertsList = [
...old,
{ type: "error", data: _.cloneDeep(errorData), id: _.uniqueId() },
];
return newAlertsList;
});
}
// If there is a notice alert open with data, add it to the alertsList
else if (noticeOpen && noticeData) {
setNoticeOpen(false);
setAlertsList((old) => {
let newAlertsList = [
...old,
{ type: "notice", data: _.cloneDeep(noticeData), id: _.uniqueId() },
];
return newAlertsList;
});
}
// If there is a success alert open with data, add it to the alertsList
else if (successOpen && successData) {
setSuccessOpen(false);
setAlertsList((old) => {
let newAlertsList = [
...old,
{ type: "success", data: _.cloneDeep(successData), id: _.uniqueId() },
];
return newAlertsList;
});
}
}, [_, errorData, errorOpen, noticeData, noticeOpen, setErrorOpen, setNoticeOpen, setSuccessOpen, successData, successOpen]);
// Use effect hook to update alertsList when a new alert is added
useEffect(() => {
// If there is an error alert open with data, add it to the alertsList
if (errorOpen && errorData) {
setErrorOpen(false);
setAlertsList((old) => {
let newAlertsList = [
...old,
{ type: "error", data: _.cloneDeep(errorData), id: _.uniqueId() },
];
return newAlertsList;
});
}
// If there is a notice alert open with data, add it to the alertsList
else if (noticeOpen && noticeData) {
setNoticeOpen(false);
setAlertsList((old) => {
let newAlertsList = [
...old,
{ type: "notice", data: _.cloneDeep(noticeData), id: _.uniqueId() },
];
return newAlertsList;
});
}
// If there is a success alert open with data, add it to the alertsList
else if (successOpen && successData) {
setSuccessOpen(false);
setAlertsList((old) => {
let newAlertsList = [
...old,
{ type: "success", data: _.cloneDeep(successData), id: _.uniqueId() },
];
return newAlertsList;
});
}
}, [
_,
errorData,
errorOpen,
noticeData,
noticeOpen,
setErrorOpen,
setNoticeOpen,
setSuccessOpen,
successData,
successOpen,
]);
const removeAlert = (id: string) => {
setAlertsList((prevAlertsList) =>
@ -83,18 +103,27 @@ useEffect(() => {
return (
//need parent component with width and height
<div className="h-full flex flex-col">
<div className="flex grow-0 shrink basis-auto">
</div>
<div className="flex grow shrink basis-auto min-h-0 flex-1 overflow-hidden">
<ExtraSidebar />
{/* Main area */}
<main className="min-w-0 flex-1 border-t border-gray-200 dark:border-gray-700 flex">
{/* Primary column */}
<div className="w-full h-full">
<TabsManagerComponent></TabsManagerComponent>
</div>
</main>
</div>
<div className="flex grow-0 shrink basis-auto"></div>
<ErrorBoundary
onReset={() => {
window.localStorage.removeItem("tabsData");
window.localStorage.clear();
hardReset()
window.location.href = window.location.href;
}}
FallbackComponent={CrashErrorComponent}
>
<div className="flex grow shrink basis-auto min-h-0 flex-1 overflow-hidden">
<ExtraSidebar />
{/* Main area */}
<main className="min-w-0 flex-1 border-t border-gray-200 dark:border-gray-700 flex">
{/* Primary column */}
<div className="w-full h-full">
<TabsManagerComponent></TabsManagerComponent>
</div>
</main>
</div>
</ErrorBoundary>
<div></div>
<div className="flex z-40 flex-col-reverse fixed bottom-5 left-5">
{alertsList.map((alert) => (
@ -126,7 +155,13 @@ useEffect(() => {
</div>
))}
</div>
<a target={"_blank"} href="https://logspace.ai/" className="absolute bottom-1 left-1 text-gray-500 text-xs cursor-pointer font-sans tracking-wide">Created by Logspace</a>
<a
target={"_blank"}
href="https://logspace.ai/"
className="absolute bottom-1 left-1 text-gray-500 text-xs cursor-pointer font-sans tracking-wide"
>
Created by Logspace
</a>
</div>
);
}

View file

@ -0,0 +1,31 @@
export default function CrashErrorComponent({ error, resetErrorBoundary }) {
return (
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-gray-800 bg-opacity-50 z-50">
<div className="bg-white max-w-4xl h-1/3 min-h-fit rounded-lg shadow-lg p-8 text-start flex flex-col justify-evenly">
<h1 className="text-red-500 text-3xl mb-4">Oops! An unknown error has occurred.</h1>
<p className="text-gray-700 mb-4 text-xl">
Please click the 'Reset Application' button
to restore the application's state. If the error persists, please
create an issue on our GitHub page. We apologize for any inconvenience
this may have caused.
</p>
<div className="flex justify-center">
<button
onClick={resetErrorBoundary}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mr-4"
>
Reset Application
</button>
<a
href="https://github.com/logspace-ai/langflow/issues/new"
target="_blank"
rel="noopener noreferrer"
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
>
Create Issue
</a>
</div>
</div>
</div>
);
}

View file

@ -15,7 +15,8 @@ const TabsContextInitialValue: TabsContextType = {
downloadFlow: (flow:FlowType) => {},
uploadFlow: () => {},
lockChat: false,
setLockChat:(prevState:boolean)=>{}
setLockChat:(prevState:boolean)=>{},
hardReset:()=>{}
};
export const TabsContext = createContext<TabsContextType>(
@ -54,6 +55,10 @@ export function TabsProvider({ children }: { children: ReactNode }) {
newNodeId.current = cookieObject.nodeId;
}
}, []);
function hardReset(){
newNodeId.current=0;
setTabIndex(0);setFlows([]);setId(0);
}
/**
* Downloads the current flow as a JSON file
@ -172,6 +177,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
return (
<TabsContext.Provider
value={{
hardReset,
lockChat,
setLockChat,
tabIndex,

View file

@ -1,18 +1,21 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import ContextWrapper from './contexts';
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
import ContextWrapper from "./contexts";
import CrashErrorComponent from "./components/CrashErrorComponent";
import { ErrorBoundary } from "react-error-boundary";
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
document.getElementById("root") as HTMLElement
);
root.render(
<ContextWrapper>
<BrowserRouter>
<App />
</BrowserRouter>
</ContextWrapper>
<ContextWrapper>
<BrowserRouter>
<App />
</BrowserRouter>
</ContextWrapper>
);
reportWebVitals();

View file

@ -9,6 +9,7 @@ export default function ButtonBox({
icon,
bgColor,
textColor,
deactivate
}: {
onClick: () => void;
title: string;
@ -16,9 +17,10 @@ export default function ButtonBox({
icon: ReactNode;
bgColor: string;
textColor: string;
deactivate?:boolean;
}) {
return (
<button onClick={onClick}>
<button disabled={deactivate} onClick={onClick}>
<div
className={classNames(
"col-span-1 flex flex-col divide-y divide-gray-200 rounded-lg text-center shadow border border-gray-300 hover:shadow-lg transform hover:scale-105",
@ -36,7 +38,7 @@ export default function ButtonBox({
<h3 className="mt-6 text-lg font-semibold text-white">{title}</h3>
<div className="mt-1 flex flex-grow flex-col justify-between">
<dt className="sr-only">{title}</dt>
<dd className="text-sm text-gray-100">{description}</dd>
<dd className="text-sm text-gray-100">{deactivate? "cooming soon":description}</dd>
</div>
</div>
</div>

View file

@ -88,13 +88,14 @@ export default function ImportModal() {
<div className="h-full w-full bg-gray-200 dark:bg-gray-900 p-4 gap-4 flex flex-row justify-center items-center">
<div className="flex h-full w-full justify-evenly items-center">
<ButtonBox
bgColor="bg-blue-500"
deactivate
bgColor="bg-slate-400"
description="Prebuilt Examples"
icon={
<DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" />
}
onClick={() => console.log("sdsds")}
textColor="text-blue-500"
textColor="text-slate-400"
title="Examples"
></ButtonBox>
<ButtonBox

View file

@ -10,6 +10,7 @@ export type TabsContextType = {
incrementNodeId: () => number;
downloadFlow: (flow:FlowType) => void;
uploadFlow: () => void;
lockChat:boolean,
setLockChat:(prevState:boolean)=>void
lockChat:boolean;
setLockChat:(prevState:boolean)=>void;
hardReset:()=>void;
};