Skip to content

Commit

Permalink
Merge pull request #124 from sima-land/38-refactor-for-redirects
Browse files Browse the repository at this point in the history
Шаг 77 #38 Рефакторинг для редиректов
  • Loading branch information
krutoo authored Mar 21, 2024
2 parents 225d08c + e7057e4 commit f618557
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 56 deletions.
35 changes: 10 additions & 25 deletions src/preset/bun-handler/providers/handler-main.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* eslint-disable require-jsdoc, jsdoc/require-jsdoc */
import { Resolve } from '../../../di';
import { KnownToken } from '../../../tokens';
import { ResponseError, applyMiddleware } from '../../../http';
import { applyMiddleware } from '../../../http';
import { HelmetContext } from '../../server/utils/regular-helmet';
import { LogLevel } from '../../../log';
import { formatHandlerError } from '../../server/utils/format-handler-error';

export function provideHandlerMain(resolve: Resolve) {
const config = resolve(KnownToken.Config.base);
Expand Down Expand Up @@ -39,37 +39,22 @@ export function provideHandlerMain(resolve: Resolve) {

return new Response(body, { headers });
} catch (error) {
let logLevel: LogLevel | null = 'error';
let message: string;
let statusCode = 500; // по умолчанию, если на этапе подготовки страницы что-то не так, отдаем 500
let redirectLocation: string | null = null;
const { response, log } = formatHandlerError(error);

if (error instanceof Error) {
message = error.message;

if (error instanceof ResponseError) {
statusCode = error.statusCode;
redirectLocation = error.redirectLocation;
logLevel = error.logLevel;
}
} else {
message = String(error);
}

if (logLevel && logger[logLevel]) {
logger[logLevel](error);
if (log.level && logger[log.level]) {
logger[log.level](error);
}

if (statusCode > 299 && statusCode < 400 && redirectLocation) {
if (response.status > 299 && response.status < 400 && response.redirectLocation) {
return new Response(null, {
status: statusCode,
status: response.status,
headers: {
Location: redirectLocation,
Location: response.redirectLocation,
},
});
} else {
return new Response(message, {
status: statusCode,
return new Response(response.body, {
status: response.status,
});
}
}
Expand Down
43 changes: 14 additions & 29 deletions src/preset/node-handler/providers/handler-main.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { Resolve } from '../../../di';
import type express from 'express';
import { KnownToken } from '../../../tokens';
import { HelmetContext } from '../../server/utils/regular-helmet';
import { ResponseError } from '../../../http';
import { LogLevel } from '../../../log';
import { formatHandlerError } from '../../server/utils/format-handler-error';

/**
* Провайдер главной функции обработчика входящего http-запроса.
* @param resolve Функция для получения зависимости по токену.
* @return Главная функция.
*/
export function provideHandlerMain(resolve: Resolve): VoidFunction {
export function provideHandlerMain(resolve: Resolve): express.Handler {
const config = resolve(KnownToken.Config.base);
const logger = resolve(KnownToken.logger);
const context = resolve(KnownToken.ExpressHandler.context);
Expand All @@ -18,7 +18,7 @@ export function provideHandlerMain(resolve: Resolve): VoidFunction {
const extras = resolve(KnownToken.Http.Handler.Response.specificExtras);
const Helmet = resolve(KnownToken.Http.Handler.Page.helmet);
const abortController = resolve(KnownToken.Http.Fetch.abortController);
const format = resolve(KnownToken.Http.Handler.Page.formatResponse);
const formatResponse = resolve(KnownToken.Http.Handler.Page.formatResponse);

const getAssets = typeof assetsInit === 'function' ? assetsInit : () => assetsInit;

Expand All @@ -37,42 +37,27 @@ export function provideHandlerMain(resolve: Resolve): VoidFunction {
const assets = await getAssets();
const meta = extras.getMeta();

const { body, headers } = await format(
const jsx = (
<HelmetContext.Provider value={{ title: config.appName, assets }}>
<Helmet>{await render()}</Helmet>
</HelmetContext.Provider>,
assets,
meta,
</HelmetContext.Provider>
);

const { body, headers } = await formatResponse(jsx, assets, meta);

headers.forEach((hValue, hName) => context.res.setHeader(hName, hValue));
context.res.send(body);
} catch (error) {
let logLevel: LogLevel | null = 'error';
let message: string;
let statusCode = 500; // по умолчанию, если на этапе подготовки страницы что-то не так, отдаем 500
let redirectLocation: string | null = null;

if (error instanceof Error) {
message = error.message;

if (error instanceof ResponseError) {
statusCode = error.statusCode;
redirectLocation = error.redirectLocation;
logLevel = error.logLevel;
}
} else {
message = String(error);
}
const { response, log } = formatHandlerError(error);

if (statusCode > 299 && statusCode < 400 && redirectLocation) {
context.res.redirect(statusCode, redirectLocation);
if (response.status > 299 && response.status < 400 && response.redirectLocation) {
context.res.redirect(response.status, response.redirectLocation);
} else {
context.res.status(statusCode).send(message);
context.res.status(response.status).send(response.body);
}

if (logLevel && logger[logLevel]) {
logger[logLevel](error);
if (log.level && logger[log.level]) {
logger[log.level](error);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/preset/node/utils/handler-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function HandlerProvider(getApp: () => Application): Provider<express.Han

app.attach(parent);
app.bind(KnownToken.ExpressHandler.context).toValue({ req, res, next });
app.get(KnownToken.ExpressHandler.main)();
app.get(KnownToken.ExpressHandler.main)(req, res, next);
};
};
}
38 changes: 38 additions & 0 deletions src/preset/server/utils/format-handler-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ResponseError } from '../../../http';
import { LogLevel } from '../../../log';

/**
* Функция форматирования ошибки обработчика запроса.
* @param error Ошибка.
* @return Формат ответа и лога ошибки.
*/
export function formatHandlerError(error: unknown) {
let logLevel: LogLevel | null = 'error';
let message: string;
let statusCode = 500; // по умолчанию, если на этапе подготовки страницы что-то не так, отдаем 500
let redirectLocation: string | null = null;

if (error instanceof Error) {
message = error.message;

if (error instanceof ResponseError) {
statusCode = error.statusCode;
redirectLocation = error.redirectLocation;
logLevel = error.logLevel;
}
} else {
message = String(error);
}

return {
response: {
status: statusCode,
body: message,
redirectLocation,
},
log: {
level: logLevel,
message,
},
};
}
2 changes: 1 addition & 1 deletion src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export const KnownToken = {
/** Токены компонентов express-обработчика. */
ExpressHandler: {
/** Токен главной функции (точки входа) обработчика. */
main: createToken<() => void>('express-handler/main'),
main: createToken<express.Handler>('express-handler/main'),

/** Токен "контекста" обработчика. Контекст содержит все аргументы, доступные обработчику (req, res, next). */
context: createToken<ExpressHandlerContext>('express-handler/context'),
Expand Down

0 comments on commit f618557

Please sign in to comment.