Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 69b117f

Browse files
error boundary part 1
1 parent 4cccfe8 commit 69b117f

File tree

5 files changed

+283
-84
lines changed

5 files changed

+283
-84
lines changed

‎client/packages/lowcoder/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"react-documents": "^1.2.1",
6969
"react-dom": "^18.2.0",
7070
"react-draggable": "^4.4.4",
71+
"react-error-boundary": "^4.0.13",
7172
"react-grid-layout": "^1.3.0",
7273
"react-helmet": "^6.1.0",
7374
"react-joyride": "^2.4.0",

‎client/packages/lowcoder/src/app.tsx‎

Lines changed: 238 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import { SystemWarning } from "./components/SystemWarning";
5353
import { getBrandingConfig } from "./redux/selectors/configSelectors";
5454
import { buildMaterialPreviewURL } from "./util/materialUtils";
5555
import GlobalInstances from 'components/GlobalInstances';
56+
import {ErrorBoundary, FallbackProps} from 'react-error-boundary';
5657

5758
const LazyUserAuthComp = React.lazy(() => import("pages/userAuth"));
5859
const LazyInviteLanding = React.lazy(() => import("pages/common/inviteLanding"));
@@ -89,18 +90,34 @@ type AppIndexProps = {
8990
};
9091

9192
class AppIndex extends React.Component<AppIndexProps, any> {
93+
constructor(props: any) {
94+
super(props);
95+
this.state = {error: null};
96+
}
9297
componentDidMount() {
9398
this.props.getCurrentUser();
9499
}
95100

96101
componentDidUpdate(prevProps: AppIndexProps) {
97-
if(prevProps.currentOrgId !== this.props.currentOrgId && this.props.currentOrgId !== '') {
102+
if (
103+
prevProps.currentOrgId !== this.props.currentOrgId &&
104+
this.props.currentOrgId !== ''
105+
) {
98106
this.props.fetchConfig(this.props.currentOrgId);
99107
}
100108
}
101-
109+
updateError = () => {
110+
this.state.error('known');
111+
};
112+
fallbackRender = ({error, resetErrorBoundary}: FallbackProps) => {
113+
return <div role="alert">
114+
<h3>Error Boundary</h3>
115+
<p>Something went wrong.</p>
116+
<button onClick={resetErrorBoundary}>Reset</button>
117+
</div>;
118+
};
102119
render() {
103-
const isTemplate = hasQueryParam("template");
120+
const isTemplate = hasQueryParam('template');
104121
const pathname = history.location.pathname;
105122

106123
// we check if we are on the public cloud
@@ -122,56 +139,157 @@ class AppIndex extends React.Component<AppIndexProps, any> {
122139
<Helmet>
123140
{<title>{this.props.brandName}</title>}
124141
{<link rel="icon" href={this.props.favicon} />}
125-
<meta name="description" content={trans("productDesc")} />
126-
<meta name="keywords" content="Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development" />
142+
<meta name="description" content={trans('productDesc')} />
143+
<meta
144+
name="keywords"
145+
content="Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development"
146+
/>
127147
<meta name="author" content="Lowcoder Software LTD" />
128148
<meta name="robots" content="index, follow" />
129149

130-
131-
<meta key="og:title" property="og:title" content={this.props.brandName} />
132-
<meta key="og:description" property="og:description" content={trans("productDesc")} />
133-
<meta key="og:image" property="og:image" content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png" />
150+
<meta
151+
key="og:title"
152+
property="og:title"
153+
content={this.props.brandName}
154+
/>
155+
<meta
156+
key="og:description"
157+
property="og:description"
158+
content={trans('productDesc')}
159+
/>
160+
<meta
161+
key="og:image"
162+
property="og:image"
163+
content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png"
164+
/>
134165
<meta key="og:url" property="og:url" content={window.location.href} />
135166
<meta key="og:type" property="og:type" content="website" />
136167

137-
<meta key="twitter:card" name="twitter:card" content="summary_large_image" />
138-
<meta key="twitter:title" name="twitter:title" content={this.props.brandName} />
139-
<meta key="twitter:description" name="twitter:description" content={trans("productDesc")} />
140-
<meta key="twitter:image" name="twitter:image" content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png" />
168+
<meta
169+
key="twitter:card"
170+
name="twitter:card"
171+
content="summary_large_image"
172+
/>
173+
<meta
174+
key="twitter:title"
175+
name="twitter:title"
176+
content={this.props.brandName}
177+
/>
178+
<meta
179+
key="twitter:description"
180+
name="twitter:description"
181+
content={trans('productDesc')}
182+
/>
183+
<meta
184+
key="twitter:image"
185+
name="twitter:image"
186+
content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png"
187+
/>
141188

142-
<meta key="viewport" name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
143-
<meta key="mobile-web-app-capable" name="mobile-web-app-capable" content="yes" />
189+
<meta
190+
key="viewport"
191+
name="viewport"
192+
content="width=device-width, initial-scale=1, shrink-to-fit=no"
193+
/>
194+
<meta
195+
key="mobile-web-app-capable"
196+
name="mobile-web-app-capable"
197+
content="yes"
198+
/>
144199
<meta key="theme-color" name="theme-color" content="#b480de" />
145200

146-
<meta key="apple-mobile-web-app-capable" name="apple-mobile-web-app-capable" content="yes" />
147-
<meta key="apple-mobile-web-app-status-bar-style" name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
148-
<meta key="apple-mobile-web-app-title" name="apple-mobile-web-app-title" content={this.props.brandName} />
149-
<link key="apple-touch-icon" rel="apple-touch-icon" href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png" />
150-
<link key="apple-touch-startup-image" rel="apple-touch-startup-image" href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png" />
201+
<meta
202+
key="apple-mobile-web-app-capable"
203+
name="apple-mobile-web-app-capable"
204+
content="yes"
205+
/>
206+
<meta
207+
key="apple-mobile-web-app-status-bar-style"
208+
name="apple-mobile-web-app-status-bar-style"
209+
content="black-translucent"
210+
/>
211+
<meta
212+
key="apple-mobile-web-app-title"
213+
name="apple-mobile-web-app-title"
214+
content={this.props.brandName}
215+
/>
216+
<link
217+
key="apple-touch-icon"
218+
rel="apple-touch-icon"
219+
href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png"
220+
/>
221+
<link
222+
key="apple-touch-startup-image"
223+
rel="apple-touch-startup-image"
224+
href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png"
225+
/>
151226

152-
<meta key="application-name" name="application-name" content={this.props.brandName} />
153-
<meta key="msapplication-TileColor" name="msapplication-TileColor" content="#b480de" />
154-
<meta key="msapplication-TileImage" name="msapplication-TileImage" content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png" />
227+
<meta
228+
key="application-name"
229+
name="application-name"
230+
content={this.props.brandName}
231+
/>
232+
<meta
233+
key="msapplication-TileColor"
234+
name="msapplication-TileColor"
235+
content="#b480de"
236+
/>
237+
<meta
238+
key="msapplication-TileImage"
239+
name="msapplication-TileImage"
240+
content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png"
241+
/>
155242
{/*}<meta key="msapplication-config" name="msapplication-config" content="https://www.yourdomain.com/path/to/browserconfig.xml" />, */}
156243

157244
<link rel="canonical" href={window.location.href} />
158245
{isLowCoderDomain && [
159246
// Adding Support for iframely to be able to embedd the component explorer in the docu
160-
<meta key="iframely:title" property="iframely:title" content={this.props.brandName} />,
161-
<meta key="iframely:description" property="iframely:description" content={trans("productDesc")} />,
247+
<meta
248+
key="iframely:title"
249+
property="iframely:title"
250+
content={this.props.brandName}
251+
/>,
252+
<meta
253+
key="iframely:description"
254+
property="iframely:description"
255+
content={trans('productDesc')}
256+
/>,
162257

163-
<link key="preconnect-googleapis" rel="preconnect" href="https://fonts.googleapis.com" />,
164-
<link key="preconnect-gstatic" rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />,
165-
<link key="font-ubuntu" href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,700;1,400&display=swap" rel="stylesheet" />,
258+
<link
259+
key="preconnect-googleapis"
260+
rel="preconnect"
261+
href="https://fonts.googleapis.com"
262+
/>,
263+
<link
264+
key="preconnect-gstatic"
265+
rel="preconnect"
266+
href="https://fonts.gstatic.com"
267+
crossOrigin="anonymous"
268+
/>,
269+
<link
270+
key="font-ubuntu"
271+
href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,700;1,400&display=swap"
272+
rel="stylesheet"
273+
/>,
166274
// adding Clearbit Support for Analytics
167-
<script key="clearbit-script" src="https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js" referrerPolicy="strict-origin-when-cross-origin" type="text/javascript"></script>
275+
<script
276+
key="clearbit-script"
277+
src="https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js"
278+
referrerPolicy="strict-origin-when-cross-origin"
279+
type="text/javascript"
280+
></script>,
168281
]}
169282
</Helmet>
170283
<SystemWarning />
171-
<Router history={history}>
172-
<Switch>
173-
174-
{/*
284+
<ErrorBoundary
285+
fallbackRender={this.fallbackRender}
286+
onReset={(details) => {
287+
this.state.error(null);
288+
}}
289+
>
290+
<Router history={history}>
291+
<Switch>
292+
{/*
175293
// we decided to show the org homepage in a own navigation page
176294
{!this.props.orgDev && !!this.props.defaultHomePage ? (
177295
<Redirect exact from={BASE_URL} to={APPLICATION_VIEW_URL(this.props.defaultHomePage, "view")}
@@ -184,55 +302,92 @@ class AppIndex extends React.Component<AppIndexProps, any> {
184302
/>
185303
)} */}
186304

187-
{!this.props.orgDev ? (
188-
<Redirect exact from={BASE_URL} to={ORG_HOME_URL} />
189-
) : (
190-
<Redirect exact from={BASE_URL} to={ALL_APPLICATIONS_URL} />
191-
)}
192-
193-
<LazyRoute exact path={IMPORT_APP_FROM_TEMPLATE_URL} component={LazyAppFromTemplate} />
194-
<LazyRoute fallback="layout" path={APP_EDITOR_URL} component={LazyAppEditor} />
195-
<LazyRoute
196-
fallback="layout"
197-
path={[
198-
USER_PROFILE_URL,
199-
NEWS_URL,
200-
ORG_HOME_URL,
201-
ALL_APPLICATIONS_URL,
202-
DATASOURCE_CREATE_URL,
203-
DATASOURCE_EDIT_URL,
204-
DATASOURCE_URL,
205-
QUERY_LIBRARY_URL,
206-
FOLDERS_URL,
207-
FOLDER_URL,
208-
TRASH_URL,
209-
SETTING,
210-
MARKETPLACE_URL,
211-
ADMIN_APP_URL,
212-
API_DOCS_URL,
213-
]}
214-
// component={ApplicationListPage}
215-
component={LazyApplicationHome}
216-
/>
217-
<LazyRoute path={USER_AUTH_URL} component={LazyUserAuthComp} />
218-
<LazyRoute path={ORG_AUTH_LOGIN_URL} component={LazyUserAuthComp} />
219-
<LazyRoute path={ORG_AUTH_REGISTER_URL} component={LazyUserAuthComp} />
220-
<LazyRoute path={ORG_AUTH_FORGOT_PASSWORD_URL} component={LazyUserAuthComp} />
221-
<LazyRoute path={ORG_AUTH_RESET_PASSWORD_URL} component={LazyUserAuthComp} />
222-
<LazyRoute path={INVITE_LANDING_URL} component={LazyInviteLanding} />
223-
<LazyRoute path={`${COMPONENT_DOC_URL}/:name`} component={LazyComponentDoc} />
224-
<LazyRoute path={`/playground/:name/:dsl`} component={LazyComponentPlayground} />
225-
<Redirect to={`${COMPONENT_DOC_URL}/input`} path="/components" />
226-
{developEnv() && (
227-
<>
228-
<LazyRoute path="/debug_comp/:name" component={LazyDebugComp} />
229-
<LazyRoute exact path="/debug_comp" component={LazyDebugComp} />
230-
<LazyRoute path="/debug_editor" component={LazyAppEditor} />
231-
<LazyRoute path="/debug_new" component={LazyDebugNewComp} />
232-
</>
233-
)}
234-
</Switch>
235-
</Router>
305+
{!this.props.orgDev ? (
306+
<Redirect exact from={BASE_URL} to={ORG_HOME_URL} />
307+
) : (
308+
<Redirect exact from={BASE_URL} to={ALL_APPLICATIONS_URL} />
309+
)}
310+
311+
<LazyRoute
312+
exact
313+
path={IMPORT_APP_FROM_TEMPLATE_URL}
314+
component={LazyAppFromTemplate}
315+
/>
316+
<LazyRoute
317+
fallback="layout"
318+
path={APP_EDITOR_URL}
319+
component={LazyAppEditor}
320+
/>
321+
<LazyRoute
322+
fallback="layout"
323+
path={[
324+
USER_PROFILE_URL,
325+
NEWS_URL,
326+
ORG_HOME_URL,
327+
ALL_APPLICATIONS_URL,
328+
DATASOURCE_CREATE_URL,
329+
DATASOURCE_EDIT_URL,
330+
DATASOURCE_URL,
331+
QUERY_LIBRARY_URL,
332+
FOLDERS_URL,
333+
FOLDER_URL,
334+
TRASH_URL,
335+
SETTING,
336+
MARKETPLACE_URL,
337+
ADMIN_APP_URL,
338+
API_DOCS_URL,
339+
]}
340+
// component={ApplicationListPage}
341+
component={LazyApplicationHome}
342+
/>
343+
<LazyRoute path={USER_AUTH_URL} component={LazyUserAuthComp} />
344+
<LazyRoute
345+
path={ORG_AUTH_LOGIN_URL}
346+
component={LazyUserAuthComp}
347+
/>
348+
<LazyRoute
349+
path={ORG_AUTH_REGISTER_URL}
350+
component={LazyUserAuthComp}
351+
/>
352+
<LazyRoute
353+
path={ORG_AUTH_FORGOT_PASSWORD_URL}
354+
component={LazyUserAuthComp}
355+
/>
356+
<LazyRoute
357+
path={ORG_AUTH_RESET_PASSWORD_URL}
358+
component={LazyUserAuthComp}
359+
/>
360+
<LazyRoute
361+
path={INVITE_LANDING_URL}
362+
component={LazyInviteLanding}
363+
/>
364+
<LazyRoute
365+
path={`${COMPONENT_DOC_URL}/:name`}
366+
component={LazyComponentDoc}
367+
/>
368+
<LazyRoute
369+
path={`/playground/:name/:dsl`}
370+
component={LazyComponentPlayground}
371+
/>
372+
<Redirect to={`${COMPONENT_DOC_URL}/input`} path="/components" />
373+
{developEnv() && (
374+
<>
375+
<LazyRoute
376+
path="/debug_comp/:name"
377+
component={LazyDebugComp}
378+
/>
379+
<LazyRoute
380+
exact
381+
path="/debug_comp"
382+
component={LazyDebugComp}
383+
/>
384+
<LazyRoute path="/debug_editor" component={LazyAppEditor} />
385+
<LazyRoute path="/debug_new" component={LazyDebugNewComp} />
386+
</>
387+
)}
388+
</Switch>
389+
</Router>
390+
</ErrorBoundary>
236391
</Wrapper>
237392
);
238393
}
@@ -267,7 +422,7 @@ export function bootstrap() {
267422
const root = createRoot(container!);
268423
root.render(
269424
<Provider store={reduxStore}>
270-
<AppIndexWithProps />
425+
<AppIndexWithProps />
271426
</Provider>
272427
);
273428
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /