diff --git a/client/src/app.tsx b/client/src/app.tsx index 0008f207..84740f8c 100644 --- a/client/src/app.tsx +++ b/client/src/app.tsx @@ -46,10 +46,11 @@ addLocaleData([...en, ...ru]); export const App = () => { return ( - + - + { window.__HAS_ERROR__ && } + diff --git a/client/src/pages/server-error/server-error.component.tsx b/client/src/pages/server-error/server-error.component.tsx index f2bd3d89..2d2210bb 100644 --- a/client/src/pages/server-error/server-error.component.tsx +++ b/client/src/pages/server-error/server-error.component.tsx @@ -1,5 +1,4 @@ import * as React from 'react'; -import { Link } from 'react-router-dom'; import './server-error.scss'; @@ -11,7 +10,7 @@ export class ServerErrorComponent extends React.PureComponent { Unhandled Error occurred - Go back to home + Go back to home ); } diff --git a/client/src/typings.d.ts b/client/src/typings.d.ts index b406f785..93bec26b 100644 --- a/client/src/typings.d.ts +++ b/client/src/typings.d.ts @@ -13,6 +13,7 @@ declare module 'highcharts-react-official'; interface Window { __PRELOADED_STATE__: any; + __HAS_ERROR__: number; __APP_CONFIG__: { apiUrl: string; }; diff --git a/server/app.server.tsx b/server/app.server.tsx index bf847129..33b06574 100644 --- a/server/app.server.tsx +++ b/server/app.server.tsx @@ -21,7 +21,7 @@ const TextComponent = (props: any) => { addLocaleData([...en, ...ru]); -export const App = ({ location, context, preloadedState }: any) => { +export const App = ({ location, context, preloadedState, hasError }: any) => { const languages = ['en', 'ru']; let locale = languages[0]; @@ -31,29 +31,8 @@ export const App = ({ location, context, preloadedState }: any) => { locale = pathLanguage; } - preloadedState.settings.locale = locale; - - const AppStore = configureStore(preloadedState); - - return ( - - - - - - - - ); -}; - -export const Error = ({ location, context, preloadedState }: any) => { - const languages = ['en', 'ru']; - let locale = languages[0]; - - const pathLanguage = location.split('/')[1]; - - if (languages.includes(pathLanguage)) { - locale = pathLanguage; + if (!preloadedState.settings) { + preloadedState.settings = {}; } preloadedState.settings.locale = locale; @@ -62,9 +41,9 @@ export const Error = ({ location, context, preloadedState }: any) => { return ( - + - + { hasError ? : } diff --git a/server/index.tsx b/server/index.tsx index 44368627..393aa0d8 100644 --- a/server/index.tsx +++ b/server/index.tsx @@ -10,13 +10,13 @@ import sprite from 'svg-sprite-loader/runtime/sprite.build'; import { serverHtml } from './server.html'; -import { App, Error } from './app.server'; +import { App } from './app.server'; import '../client/src/config/axios.config'; import { AddressPage } from './pages/address.page'; import { BlockPage } from './pages/block.page'; -import { ChartImage, generateImages } from './pages/chart-image'; +import { ChartImage, runImageGeneration } from './pages/chart-image'; import { ChartPage } from './pages/charts.page'; import { DataPage } from './pages/data.page'; import { SearchPage } from './pages/search.page'; @@ -67,49 +67,14 @@ server.use('/:locale?/search', SearchPage); server.use((req: any, res, next) => { axios.interceptors.response.use(response => response, () => { - if (req.explorer.skipError) { - return; + if (!req.explorer.skipError) { + req.explorer.hasError = true; } - - return res.redirect('/server-error'); }); next(); }); -server.use('/:locale?/server-error', (req: any, res) => { - const context: any = {}; - - const body = renderToString( - ( - - ) - ); - - const helmet = Helmet.renderStatic(); - - const htmlToRender = serverHtml({ - assets: manifest.assets, - body, - helmet, - preloadedState: req.explorer.preloadedState, - spriteContent: sprite.stringify() - }); - - if (context.url) { - res.writeHead(302, { - Location: context.url - }); - - res.end(); - } else { - res.write(htmlToRender); - res.end(); - } -}); - server.use('*', Preloader); server.use('/:locale?', DataPage); @@ -128,6 +93,7 @@ server.get('*', (req: any, res) => { ( ) ); @@ -137,6 +103,7 @@ server.get('*', (req: any, res) => { const htmlToRender = serverHtml({ assets: manifest.assets, body, + hasError: req.explorer.hasError, helmet, preloadedState: req.explorer.preloadedState, spriteContent: sprite.stringify() @@ -157,22 +124,6 @@ server.get('*', (req: any, res) => { server.listen(port, () => { console.debug(`App is listening on port ${port}!`); - generateImages() - .then(() => { - console.debug('images generated...'); - }) - .catch((e) => { - console.debug(e); - }); - - setInterval(() => { - generateImages() - .then(() => { - console.debug('images generated...'); - }) - .catch((e) => { - console.debug(e); - }); - }, 1000 * 60 * 10); + runImageGeneration(); }); diff --git a/server/pages/address.page.tsx b/server/pages/address.page.tsx index 4ec6ce16..771fe9d9 100644 --- a/server/pages/address.page.tsx +++ b/server/pages/address.page.tsx @@ -30,6 +30,11 @@ const render = (req: any, res: any, next: any) => { next(); }); + }) + .catch(() => { + req.explorer.hasError = true; + + next(); }); }; diff --git a/server/pages/block.page.tsx b/server/pages/block.page.tsx index 330a4e85..39f0f305 100644 --- a/server/pages/block.page.tsx +++ b/server/pages/block.page.tsx @@ -24,6 +24,11 @@ const render = (req: any, res: any, next: any) => { } }; + next(); + }) + .catch(() => { + req.explorer.hasError = true; + next(); }); }; diff --git a/server/pages/chart-image.tsx b/server/pages/chart-image.tsx index 9c7eaf61..dd4bb1bd 100644 --- a/server/pages/chart-image.tsx +++ b/server/pages/chart-image.tsx @@ -9,7 +9,7 @@ export const ChartImage = express.Router(); const cacheRoot = fs.realpathSync(process.cwd()) + '/tmp/cache/'; fs.ensureDirSync(cacheRoot); -export const generateImages = async () => { +const generateImages = async () => { const chartTypes = [ 'total', 'blockchain-size', @@ -54,3 +54,22 @@ export const generateImages = async () => { }; ChartImage.use('/', express.static(cacheRoot)); + +export const runImageGeneration = () => { + console.debug('[PROGRESS] Generating charts preview images...'); + + generateImages() + .then(() => { + console.debug('[SUCCESS] Charts preview generated!'); + + setTimeout(() => { + runImageGeneration(); + }, 1000 * 60 * 10); + }) + .catch((e) => { + console.debug('[FAILURE] Charts preview generation failed!'); + console.debug(e); + + runImageGeneration(); + }); +}; diff --git a/server/pages/charts.page.tsx b/server/pages/charts.page.tsx index 557d9590..dd71f4b1 100644 --- a/server/pages/charts.page.tsx +++ b/server/pages/charts.page.tsx @@ -21,6 +21,11 @@ ChartPage.get('/*', (req: any, res, next) => { chart: preloadedState, }; + next(); + }) + .catch(() => { + req.explorer.hasError = true; + next(); }); }); diff --git a/server/pages/data.page.tsx b/server/pages/data.page.tsx index 01e9f8d0..c4735f08 100644 --- a/server/pages/data.page.tsx +++ b/server/pages/data.page.tsx @@ -23,6 +23,11 @@ DataPage.get('/', (req: any, res, next) => { req.explorer.preloadedState = { ...req.explorer.preloadedState, ...preloadedState }; + next(); + }) + .catch(() => { + req.explorer.hasError = true; + next(); }); }); diff --git a/server/pages/stats.page.tsx b/server/pages/stats.page.tsx index 16a24cae..526688cf 100644 --- a/server/pages/stats.page.tsx +++ b/server/pages/stats.page.tsx @@ -25,6 +25,11 @@ StatsPage.get('/', (req: any, res, next) => { } }; + next(); + }) + .catch(() => { + req.explorer.hasError = true; + next(); }); }); diff --git a/server/pages/transaction.page.tsx b/server/pages/transaction.page.tsx index 122baa11..917dd366 100644 --- a/server/pages/transaction.page.tsx +++ b/server/pages/transaction.page.tsx @@ -25,6 +25,11 @@ const render = (req: any, res: any, next: any) => { } }; + next(); + }) + .catch(() => { + req.explorer.hasError = true; + next(); }); }; diff --git a/server/preloader.tsx b/server/preloader.tsx index e5a06251..559fb60a 100644 --- a/server/preloader.tsx +++ b/server/preloader.tsx @@ -30,7 +30,7 @@ Preloader.get('*', (req: any, res, next) => { const apiPreloadedState = apiReducer(apiInitialState, { payload: { - data: apiData, + data: apiData }, type: GET_API_SUCCESS }); @@ -39,7 +39,7 @@ Preloader.get('*', (req: any, res, next) => { ...req.explorer.preloadedState, api: { ...apiPreloadedState, - preloaded: true, + preloaded: true }, settings: { isScriptsDisplayed: true, @@ -51,6 +51,10 @@ Preloader.get('*', (req: any, res, next) => { } }; + next(); + }) + .catch(() => { + req.explorer.hasError = true; next(); }); }); diff --git a/server/server.html.tsx b/server/server.html.tsx index 47166107..98955200 100644 --- a/server/server.html.tsx +++ b/server/server.html.tsx @@ -1,4 +1,4 @@ -export const serverHtml = ({ body, assets, helmet, spriteContent, preloadedState }: { body: string, assets: any, helmet: any, spriteContent: any, preloadedState: any }) => ` +export const serverHtml = ({ body, assets, helmet, spriteContent, preloadedState, hasError }: { body: string, assets: any, helmet: any, spriteContent: any, preloadedState: any, hasError: boolean }) => ` @@ -21,6 +21,7 @@ export const serverHtml = ({ body, assets, helmet, spriteContent, preloadedState JSON.stringify(preloadedState) .replace(/