Commit bce1d81c authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #251 from blockscout/debug-ci

debug CI
parents daf3fce3 8a1f2e5f
...@@ -7,10 +7,6 @@ const baseUrl = [ ...@@ -7,10 +7,6 @@ const baseUrl = [
process.env.NEXT_PUBLIC_VERCEL_URL || process.env.NEXT_PUBLIC_APP_HOST, process.env.NEXT_PUBLIC_VERCEL_URL || process.env.NEXT_PUBLIC_APP_HOST,
process.env.NEXT_PUBLIC_APP_PORT ? ':' + process.env.NEXT_PUBLIC_APP_PORT : '', process.env.NEXT_PUBLIC_APP_PORT ? ':' + process.env.NEXT_PUBLIC_APP_PORT : '',
].join(''); ].join('');
const apiUrl = [
process.env.NEXT_PUBLIC_API_ENDPOINT || 'https://blockscout.com',
process.env.NEXT_PUBLIC_API_BASE_PATH,
].filter(Boolean).join('');
const config = Object.freeze({ const config = Object.freeze({
env, env,
...@@ -41,7 +37,10 @@ const config = Object.freeze({ ...@@ -41,7 +37,10 @@ const config = Object.freeze({
host: process.env.NEXT_PUBLIC_APP_HOST, host: process.env.NEXT_PUBLIC_APP_HOST,
port: process.env.NEXT_PUBLIC_APP_PORT, port: process.env.NEXT_PUBLIC_APP_PORT,
baseUrl, baseUrl,
apiUrl, api: {
endpoint: process.env.NEXT_PUBLIC_API_ENDPOINT || 'https://blockscout.com',
basePath: process.env.NEXT_PUBLIC_API_BASE_PATH || '',
},
}); });
export default config; export default config;
...@@ -3,6 +3,7 @@ import type { NextApiRequest } from 'next'; ...@@ -3,6 +3,7 @@ import type { NextApiRequest } from 'next';
import type { RequestInit, Response } from 'node-fetch'; import type { RequestInit, Response } from 'node-fetch';
import nodeFetch from 'node-fetch'; import nodeFetch from 'node-fetch';
import { httpLogger } from 'lib/api/logger';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
// first arg can be only a string // first arg can be only a string
...@@ -14,7 +15,13 @@ export default function fetchFactory(_req: NextApiRequest) { ...@@ -14,7 +15,13 @@ export default function fetchFactory(_req: NextApiRequest) {
'content-type': 'application/json', 'content-type': 'application/json',
cookie: `${ cookies.NAMES.API_TOKEN }=${ _req.cookies[cookies.NAMES.API_TOKEN] }`, cookie: `${ cookies.NAMES.API_TOKEN }=${ _req.cookies[cookies.NAMES.API_TOKEN] }`,
}; };
const url = new URL(path, appConfig.apiUrl); const url = new URL(path, appConfig.api.endpoint);
httpLogger.logger.info({
message: 'Trying to call API',
url,
req: _req,
});
return nodeFetch(url.toString(), { return nodeFetch(url.toString(), {
headers, headers,
......
// import * as Sentry from '@sentry/nextjs'; // import * as Sentry from '@sentry/nextjs';
import appConfig from 'configs/app/config';
import type { NextApiRequest } from 'next'; import type { NextApiRequest } from 'next';
import * as cookies from 'lib/cookies';
export default function getUrlWithNetwork(_req: NextApiRequest, path: string) { export default function getUrlWithNetwork(_req: NextApiRequest, path: string) {
const networkType = _req.cookies[cookies.NAMES.NETWORK_TYPE]; return [
const networkSubType = _req.cookies[cookies.NAMES.NETWORK_SUB_TYPE]; appConfig.api.basePath,
path,
// if (!networkType) { ]
// TODO setup sentry for NodeJS .filter((segment) => segment !== '' && segment !== '/')
// we probably do not need to if we will do api request from client directly .join('');
// Sentry.captureException(new Error('Incorrect network'), { extra: { networkType, networkSubType } });
// }
return `/${ networkType }${ networkSubType ? '/' + networkSubType : '' }/${ path }`;
} }
...@@ -2,11 +2,14 @@ import type { NextApiRequest, NextApiResponse } from 'next'; ...@@ -2,11 +2,14 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import fetchFactory from 'lib/api/fetch'; import fetchFactory from 'lib/api/fetch';
import getUrlWithNetwork from 'lib/api/getUrlWithNetwork'; import getUrlWithNetwork from 'lib/api/getUrlWithNetwork';
import { httpLogger } from 'lib/api/logger';
type Methods = 'GET' | 'POST' | 'PUT' | 'DELETE'; type Methods = 'GET' | 'POST' | 'PUT' | 'DELETE';
export default function createHandler(getUrl: (_req: NextApiRequest) => string, allowedMethods: Array<Methods>) { export default function createHandler(getUrl: (_req: NextApiRequest) => string, allowedMethods: Array<Methods>) {
const handler = async(_req: NextApiRequest, res: NextApiResponse) => { const handler = async(_req: NextApiRequest, res: NextApiResponse) => {
httpLogger(_req, res);
if (!_req.method || !allowedMethods.includes(_req.method as Methods)) { if (!_req.method || !allowedMethods.includes(_req.method as Methods)) {
res.setHeader('Allow', allowedMethods); res.setHeader('Allow', allowedMethods);
res.status(405).end(`Method ${ _req.method } Not Allowed`); res.status(405).end(`Method ${ _req.method } Not Allowed`);
...@@ -15,7 +18,7 @@ export default function createHandler(getUrl: (_req: NextApiRequest) => string, ...@@ -15,7 +18,7 @@ export default function createHandler(getUrl: (_req: NextApiRequest) => string,
const isBodyDisallowed = _req.method === 'GET' || _req.method === 'HEAD'; const isBodyDisallowed = _req.method === 'GET' || _req.method === 'HEAD';
const url = getUrlWithNetwork(_req, `api${ getUrl(_req) }`); const url = getUrlWithNetwork(_req, `/api${ getUrl(_req) }`);
const fetch = fetchFactory(_req); const fetch = fetchFactory(_req);
const response = await fetch(url, { const response = await fetch(url, {
method: _req.method, method: _req.method,
...@@ -38,6 +41,8 @@ export default function createHandler(getUrl: (_req: NextApiRequest) => string, ...@@ -38,6 +41,8 @@ export default function createHandler(getUrl: (_req: NextApiRequest) => string,
responseError = defaultError; responseError = defaultError;
} }
httpLogger.logger.error({ err: responseError, url: _req.url });
res.status(500).json(responseError); res.status(500).json(responseError);
}; };
......
import pino from 'pino-http';
export const httpLogger = pino();
...@@ -5,8 +5,6 @@ import isBrowser from './isBrowser'; ...@@ -5,8 +5,6 @@ import isBrowser from './isBrowser';
export enum NAMES { export enum NAMES {
NAV_BAR_COLLAPSED='nav_bar_collapsed', NAV_BAR_COLLAPSED='nav_bar_collapsed',
NETWORK_TYPE='network_type',
NETWORK_SUB_TYPE='network_sub_type',
API_TOKEN='_explorer_key', API_TOKEN='_explorer_key',
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
}, },
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",
"dev:poa_core": "./node_modules/.bin/dotenv -e ./configs/envs/.env.poa_core -e ./configs/envs/.env.common -e ./configs/envs/.env.secrets next dev", "dev:poa_core": "./node_modules/.bin/dotenv -e ./configs/envs/.env.poa_core -e ./configs/envs/.env.common -e ./configs/envs/.env.secrets next dev | ./node_modules/.bin/pino-pretty",
"build": "next build", "build": "next build",
"build:vercel": "./node_modules/.bin/dotenv -e ./configs/envs/.env.poa_core -e ./configs/envs/.env.common next build", "build:vercel": "./node_modules/.bin/dotenv -e ./configs/envs/.env.poa_core -e ./configs/envs/.env.common next build",
"build:docker": "docker build --build-arg GIT_COMMIT_SHA=$(git rev-parse HEAD) -t blockscout ./", "build:docker": "docker build --build-arg GIT_COMMIT_SHA=$(git rev-parse HEAD) -t blockscout ./",
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
"next": "12.2.5", "next": "12.2.5",
"next-react-svg": "1.1.3", "next-react-svg": "1.1.3",
"node-fetch": "^3.2.9", "node-fetch": "^3.2.9",
"pino-http": "^8.2.1",
"pino-pretty": "^9.1.1",
"react": "18.1.0", "react": "18.1.0",
"react-dom": "18.1.0", "react-dom": "18.1.0",
"react-hook-form": "^7.33.1", "react-hook-form": "^7.33.1",
......
...@@ -2,9 +2,12 @@ import type { NextApiRequest, NextApiResponse } from 'next'; ...@@ -2,9 +2,12 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import fetchFactory from 'lib/api/fetch'; import fetchFactory from 'lib/api/fetch';
import getUrlWithNetwork from 'lib/api/getUrlWithNetwork'; import getUrlWithNetwork from 'lib/api/getUrlWithNetwork';
import { httpLogger } from 'lib/api/logger';
export default async function csrfHandler(_req: NextApiRequest, res: NextApiResponse) { export default async function csrfHandler(_req: NextApiRequest, res: NextApiResponse) {
const url = getUrlWithNetwork(_req, `api/account/v1/get_csrf`); httpLogger(_req, res);
const url = getUrlWithNetwork(_req, `/api/account/v1/get_csrf`);
const fetch = fetchFactory(_req); const fetch = fetchFactory(_req);
const response = await fetch(url); const response = await fetch(url);
...@@ -14,5 +17,8 @@ export default async function csrfHandler(_req: NextApiRequest, res: NextApiResp ...@@ -14,5 +17,8 @@ export default async function csrfHandler(_req: NextApiRequest, res: NextApiResp
return; return;
} }
res.status(500).json({ statusText: response.statusText, status: response.status }); const responseError = { statusText: response.statusText, status: response.status };
httpLogger.logger.error({ err: responseError, url: _req.url });
res.status(500).json(responseError);
} }
...@@ -6,15 +6,19 @@ import type { TWatchlistItem } from 'types/client/account'; ...@@ -6,15 +6,19 @@ import type { TWatchlistItem } from 'types/client/account';
import fetchFactory from 'lib/api/fetch'; import fetchFactory from 'lib/api/fetch';
import getUrlWithNetwork from 'lib/api/getUrlWithNetwork'; import getUrlWithNetwork from 'lib/api/getUrlWithNetwork';
import { httpLogger } from 'lib/api/logger';
const watchlistWithTokensHandler = async(_req: NextApiRequest, res: NextApiResponse<Array<TWatchlistItem>>) => { const watchlistWithTokensHandler = async(_req: NextApiRequest, res: NextApiResponse<Array<TWatchlistItem>>) => {
httpLogger(_req, res);
const fetch = fetchFactory(_req); const fetch = fetchFactory(_req);
const url = getUrlWithNetwork(_req, 'api/account/v1/user/watchlist'); const url = getUrlWithNetwork(_req, '/api/account/v1/user/watchlist');
const watchlistResponse = await fetch(url, { method: 'GET' }); const watchlistResponse = await fetch(url, { method: 'GET' });
const watchlistData = await watchlistResponse.json() as WatchlistAddresses; const watchlistData = await watchlistResponse.json() as WatchlistAddresses;
if (watchlistResponse.status !== 200) { if (watchlistResponse.status !== 200) {
httpLogger.logger.error({ err: { statusText: 'Watchlist token error', status: 500 }, url: _req.url });
res.status(500).end(watchlistData || 'Unknown error'); res.status(500).end(watchlistData || 'Unknown error');
return; return;
} }
......
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import * as cookies from 'lib/cookies';
import useFetch from 'lib/hooks/useFetch'; import useFetch from 'lib/hooks/useFetch';
import PageContent from 'ui/shared/Page/PageContent'; import PageContent from 'ui/shared/Page/PageContent';
import Header from 'ui/snippets/header/Header'; import Header from 'ui/snippets/header/Header';
...@@ -15,23 +13,10 @@ interface Props { ...@@ -15,23 +13,10 @@ interface Props {
} }
const Page = ({ children, wrapChildren = true }: Props) => { const Page = ({ children, wrapChildren = true }: Props) => {
const router = useRouter();
const fetch = useFetch(); const fetch = useFetch();
const networkType = router.query.network_type;
const networkSubType = router.query.network_sub_type;
useQuery<unknown, unknown, unknown>([ 'csrf' ], async() => await fetch('/api/account/csrf')); useQuery<unknown, unknown, unknown>([ 'csrf' ], async() => await fetch('/api/account/csrf'));
React.useEffect(() => {
if (typeof networkType === 'string') {
cookies.set(cookies.NAMES.NETWORK_TYPE, networkType);
}
if (typeof networkSubType === 'string') {
cookies.set(cookies.NAMES.NETWORK_SUB_TYPE, networkSubType);
}
}, [ networkType, networkSubType ]);
const renderedChildren = wrapChildren ? ( const renderedChildren = wrapChildren ? (
<PageContent>{ children }</PageContent> <PageContent>{ children }</PageContent>
) : children; ) : children;
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment