From 7d80ea2fd356063cb0919b87efc83d1827b846d6 Mon Sep 17 00:00:00 2001 From: Fritz Lin Date: Sat, 18 Apr 2020 15:01:22 +0800 Subject: [PATCH] chore: error-handling, react-unmount-node --- README.md | 3 ++- src/hooks/useApi.ts | 8 ++++++-- src/playground/Playground.tsx | 23 ++++++++++++++++++---- src/playground/babelMaster.ts | 3 ++- src/playground/util.tsx | 36 +++++++++++++---------------------- 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 08014ee..feddfc0 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,9 @@ Visit: https://coldemo.github.io/ - [ ] vscode tsconfig src/\* alias (being reverted by npm-run-dev) - [ ] antd4, safe js exec sandbox - see pureproxy -- [ ] storage list, reset btn, sandboxNode, batch-screenshot, responsive-improve - [ ] lang ts/tsx/vue/py/rb/java +- [ ] storage list, reset btn, responsive, screenshot +- [ ] error-handling, sandboxNode - [x] gh-pages, lang js/jsx, react/vue, umd-hack - [x] code read from url, storybook cards - [x] web worker for babel transform diff --git a/src/hooks/useApi.ts b/src/hooks/useApi.ts index 81f5f24..622407b 100644 --- a/src/hooks/useApi.ts +++ b/src/hooks/useApi.ts @@ -15,6 +15,7 @@ type Request = ( export interface UseApiObj { request: Request; + error: Error | null; response: AxiosResponse | null; getData: () => DT; loading: boolean; @@ -34,6 +35,7 @@ export let useApi = ( ): UseApiObj => { let [response, setResponse] = useState | null>(null); let [loading, setLoading] = useState(false); + let [error, setError] = useState(null); let request: Request = useCallback( async (patch = {}) => { @@ -51,8 +53,10 @@ export let useApi = ( ...patch, }); setResponse(response); + setError(null); } catch (err) { - // @todo + setResponse(null); + setError(err); } finally { setLoading(false); } @@ -64,5 +68,5 @@ export let useApi = ( return parseData(response); }, [parseData, response]); - return { request, response, getData, loading }; + return { request, error, response, getData, loading }; }; diff --git a/src/playground/Playground.tsx b/src/playground/Playground.tsx index 632ddc2..ad59b4d 100644 --- a/src/playground/Playground.tsx +++ b/src/playground/Playground.tsx @@ -70,9 +70,12 @@ export let Playground: React.FC = () => { response: respIndex, loading: loadingIndex, } = useApi('GET', 'code/index.yml'); - let { request: reqCode, response: respCode, loading: loadingCode } = useApi< - string - >('GET', 'code/:file'); + let { + request: reqCode, + error: errReqCode, + response: respCode, + loading: loadingCode, + } = useApi('GET', 'code/:file'); let preloading = loadingIndex || loadingCode; useEffect(() => { @@ -89,12 +92,14 @@ export let Playground: React.FC = () => { let txt = respIndex.data; let list = txt .split(/\n/) + .map(s => s.replace(/#.*/, '').trim()) .filter(Boolean) .map(v => v.replace(/^-\s*/, '')); let defaults = list[0]; // reqCode({ pathParams: { file: file || defaults } }); history.push(`/playground/${file || defaults}`); - }, [file, history, reqCode, respIndex]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [file, respIndex]); useEffect(() => { if (respCode == null) return; @@ -102,6 +107,16 @@ export let Playground: React.FC = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [respCode]); + useEffect(() => { + // if (errReqCode && String(errReqCode).includes('status code 404')) { + // history.push('/'); // force redirect + // } + if (errReqCode) { + displayError(new Error(`${errReqCode.message} - ${file}`)); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [errReqCode]); + let [preview, setPreview] = useState(''); let [compiling, setCompiling] = useState(false); let [rendering, setRendering] = useState(false); diff --git a/src/playground/babelMaster.ts b/src/playground/babelMaster.ts index 556d3fe..50ab68d 100644 --- a/src/playground/babelMaster.ts +++ b/src/playground/babelMaster.ts @@ -4,7 +4,8 @@ let wrapCode = (code: string) => { return ` (async () => { setRendering(true) - mountNode.innerHTML = '' + // mountNode.innerHTML = '' // can cause error in react + ReactDOM.unmountComponentAtNode(mountNode) try { let { useRef, useMemo, useState, useEffect, useLayoutEffect, useReducer, useContext, useCallback, useImperativeHandle } = React ;;${code};; diff --git a/src/playground/util.tsx b/src/playground/util.tsx index e74886f..b70a67f 100644 --- a/src/playground/util.tsx +++ b/src/playground/util.tsx @@ -17,7 +17,13 @@ export let loadJsForceUmd = async ({ name: string; deps: { [key: string]: string }; }) => { - let { data: code } = await Axios(url); + let code = ''; + try { + let { data } = await Axios(url); + code = data; + } catch (err) { + throw new Error(`loadJsForceUmd - ${err.message} - ${url}`); + } code = ` (() => { let module = { exports: {} } @@ -64,29 +70,13 @@ export let loadCss = (url: string) => { }; export let appendJs = (code: string) => { - return new Promise((resolve, reject) => { - let el = document.createElement('script'); - el.innerHTML = code; - el.onload = () => { - resolve(); - }; - el.onerror = e => { - reject(new Error(`appendJs onerror - ${code.slice(0, 100)}`)); - }; - window.mountNode.appendChild(el); - }); + let el = document.createElement('script'); + el.innerHTML = code; + window.mountNode.appendChild(el); }; export let appendCss = (code: string) => { - return new Promise((resolve, reject) => { - let el = document.createElement('style'); - el.innerHTML = code; - el.onload = () => { - resolve(); - }; - el.onerror = e => { - reject(new Error(`appendCss onerror - ${code.slice(0, 100)}`)); - }; - window.mountNode.appendChild(el); - }); + let el = document.createElement('style'); + el.innerHTML = code; + window.mountNode.appendChild(el); };