From 6615d97203a0933ce2a7e8b9867d3793f8d80520 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 27 May 2026 21:39:18 +0500 Subject: [PATCH] refactor: apply asyncHandler to all route handlers --- server/src/routes/api/admin-categories.js | 53 +++++++++--------- server/src/routes/api/admin-gallery.js | 36 ++++++------- server/src/routes/api/catalog-slider.js | 39 +++++++------- server/src/routes/user-addresses.js | 66 +++++++++++------------ server/src/routes/user-cart.js | 53 +++++++++--------- server/src/routes/user-orders.js | 58 +++++++++----------- 6 files changed, 143 insertions(+), 162 deletions(-) diff --git a/server/src/routes/api/admin-categories.js b/server/src/routes/api/admin-categories.js index e33bc91..dff4775 100644 --- a/server/src/routes/api/admin-categories.js +++ b/server/src/routes/api/admin-categories.js @@ -1,3 +1,4 @@ +import { asyncHandler } from '../../lib/async-handler.js' import { getOrCreateUnspecifiedCategory, isUnspecifiedCategorySlug, @@ -6,20 +7,21 @@ import { import { prisma } from '../../lib/prisma.js' export async function registerAdminCategoryRoutes(fastify) { - fastify.get('/api/admin/categories', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - try { + fastify.get( + '/api/admin/categories', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { const items = await prisma.category.findMany({ orderBy: [{ sort: 'asc' }, { name: 'asc' }], }) return { items } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить категории' }) - } - }) + }), + ) - fastify.post('/api/admin/categories', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - try { + fastify.post( + '/api/admin/categories', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { const body = request.body ?? {} const name = String(body.name ?? '').trim() if (!name) { @@ -45,14 +47,13 @@ export async function registerAdminCategoryRoutes(fastify) { }, }) reply.code(201).send(category) - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось создать категорию' }) - } - }) + }), + ) - fastify.patch('/api/admin/categories/:id', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - try { + fastify.patch( + '/api/admin/categories/:id', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { const { id } = request.params const body = request.body ?? {} const existing = await prisma.category.findUnique({ where: { id } }) @@ -105,14 +106,13 @@ export async function registerAdminCategoryRoutes(fastify) { const updated = await prisma.category.update({ where: { id }, data }) return updated - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось обновить категорию' }) - } - }) + }), + ) - fastify.delete('/api/admin/categories/:id', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - try { + fastify.delete( + '/api/admin/categories/:id', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { const { id } = request.params const existing = await prisma.category.findUnique({ where: { id } }) if (!existing) { @@ -133,9 +133,6 @@ export async function registerAdminCategoryRoutes(fastify) { prisma.category.delete({ where: { id } }), ]) return reply.code(204).send() - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось удалить категорию' }) - } - }) + }), + ) } diff --git a/server/src/routes/api/admin-gallery.js b/server/src/routes/api/admin-gallery.js index c5954b5..c984824 100644 --- a/server/src/routes/api/admin-gallery.js +++ b/server/src/routes/api/admin-gallery.js @@ -1,5 +1,6 @@ import fs from 'node:fs/promises' import path from 'node:path' +import { asyncHandler } from '../../lib/async-handler.js' import { prisma } from '../../lib/prisma.js' import { persistMultipartImages } from '../../lib/upload-images.js' import { @@ -72,21 +73,23 @@ export async function registerAdminGalleryRoutes(fastify) { } }) - fastify.post('/api/admin/gallery/:id/resize', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - const { id } = request.params - const row = await prisma.galleryImage.findUnique({ where: { id } }) - if (!row) { - return reply.code(404).send({ error: 'Изображение не найдено' }) - } - if (row.isResized) { - return reply.code(409).send({ error: 'Изображение уже обработано' }) - } + fastify.post( + '/api/admin/gallery/:id/resize', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { + const { id } = request.params + const row = await prisma.galleryImage.findUnique({ where: { id } }) + if (!row) { + return reply.code(404).send({ error: 'Изображение не найдено' }) + } + if (row.isResized) { + return reply.code(409).send({ error: 'Изображение уже обработано' }) + } - const urlParts = row.url.replace(/^\//, '').split('/') - const fileName = urlParts[urlParts.length - 1] - const uuid = path.parse(fileName).name + const urlParts = row.url.replace(/^\//, '').split('/') + const fileName = urlParts[urlParts.length - 1] + const uuid = path.parse(fileName).name - try { const { generateAllSizes, convertOriginalToWebp } = await import('../../lib/image-resize.js') const fullPath = path.join(process.cwd(), urlParts.slice(0, -1).join('/'), fileName) @@ -99,11 +102,8 @@ export async function registerAdminGalleryRoutes(fastify) { }) return { url: newUrl } - } catch (error) { - request.log.error(error, 'Resize failed') - return reply.code(500).send({ error: 'Ошибка обработки изображения' }) - } - }) + }), + ) fastify.delete('/api/admin/gallery/:id', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { const { id } = request.params diff --git a/server/src/routes/api/catalog-slider.js b/server/src/routes/api/catalog-slider.js index 34c4087..ab99d9e 100644 --- a/server/src/routes/api/catalog-slider.js +++ b/server/src/routes/api/catalog-slider.js @@ -1,10 +1,12 @@ +import { asyncHandler } from '../../lib/async-handler.js' import { prisma } from '../../lib/prisma.js' const MAX_SLIDES = 20 export async function registerCatalogSliderRoutes(fastify) { - fastify.get('/api/catalog-slider', async (request, reply) => { - try { + fastify.get( + '/api/catalog-slider', + asyncHandler(async (request, reply) => { const slides = await prisma.catalogSliderSlide.findMany({ orderBy: { sortOrder: 'asc' }, include: { galleryImage: true }, @@ -17,14 +19,13 @@ export async function registerCatalogSliderRoutes(fastify) { textColor: s.textColor, })), } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить слайдер' }) - } - }) + }), + ) - fastify.get('/api/admin/catalog-slider', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - try { + fastify.get( + '/api/admin/catalog-slider', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { const slides = await prisma.catalogSliderSlide.findMany({ orderBy: { sortOrder: 'asc' }, include: { galleryImage: true }, @@ -38,14 +39,13 @@ export async function registerCatalogSliderRoutes(fastify) { textColor: s.textColor, })), } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить слайдер' }) - } - }) + }), + ) - fastify.put('/api/admin/catalog-slider', { preHandler: [fastify.verifyAdmin] }, async (request, reply) => { - try { + fastify.put( + '/api/admin/catalog-slider', + { preHandler: [fastify.verifyAdmin] }, + asyncHandler(async (request, reply) => { const body = request.body ?? {} const rawSlides = body.slides if (!Array.isArray(rawSlides)) { @@ -103,9 +103,6 @@ export async function registerCatalogSliderRoutes(fastify) { textColor: s.textColor, })), } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось обновить слайдер' }) - } - }) + }), + ) } diff --git a/server/src/routes/user-addresses.js b/server/src/routes/user-addresses.js index 54d3659..6ea4b30 100644 --- a/server/src/routes/user-addresses.js +++ b/server/src/routes/user-addresses.js @@ -1,3 +1,4 @@ +import { asyncHandler } from '../lib/async-handler.js' import { prisma } from '../lib/prisma.js' function normalizePhoneLite(input) { @@ -45,22 +46,23 @@ function validateAddressPayload(body, reply) { } export async function registerUserAddressRoutes(fastify) { - fastify.get('/api/me/addresses', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.get( + '/api/me/addresses', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const items = await prisma.shippingAddress.findMany({ where: { userId }, orderBy: [{ isDefault: 'desc' }, { updatedAt: 'desc' }], }) return { items } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить адреса' }) - } - }) + }), + ) - fastify.post('/api/me/addresses', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.post( + '/api/me/addresses', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const validated = validateAddressPayload(request.body, reply) if (!validated) return @@ -79,14 +81,13 @@ export async function registerUserAddressRoutes(fastify) { }) }) return reply.code(201).send({ item: created }) - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось создать адрес' }) - } - }) + }), + ) - fastify.patch('/api/me/addresses/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.patch( + '/api/me/addresses/:id', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const { id } = request.params const existing = await prisma.shippingAddress.findFirst({ where: { id, userId } }) @@ -161,14 +162,13 @@ export async function registerUserAddressRoutes(fastify) { }) return { item: updated } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось обновить адрес' }) - } - }) + }), + ) - fastify.delete('/api/me/addresses/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.delete( + '/api/me/addresses/:id', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const { id } = request.params const existing = await prisma.shippingAddress.findFirst({ where: { id, userId } }) @@ -176,14 +176,13 @@ export async function registerUserAddressRoutes(fastify) { await prisma.shippingAddress.delete({ where: { id } }) return reply.code(204).send() - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось удалить адрес' }) - } - }) + }), + ) - fastify.post('/api/me/addresses/:id/default', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.post( + '/api/me/addresses/:id/default', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const { id } = request.params const existing = await prisma.shippingAddress.findFirst({ where: { id, userId } }) @@ -195,9 +194,6 @@ export async function registerUserAddressRoutes(fastify) { }) return { item: updated } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось установить адрес по умолчанию' }) - } - }) + }), + ) } diff --git a/server/src/routes/user-cart.js b/server/src/routes/user-cart.js index 8a5ba0e..f35dfcd 100644 --- a/server/src/routes/user-cart.js +++ b/server/src/routes/user-cart.js @@ -1,8 +1,11 @@ +import { asyncHandler } from '../lib/async-handler.js' import { prisma } from '../lib/prisma.js' export async function registerUserCartRoutes(fastify) { - fastify.get('/api/me/cart', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.get( + '/api/me/cart', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const items = await prisma.cartItem.findMany({ where: { userId }, @@ -16,14 +19,13 @@ export async function registerUserCartRoutes(fastify) { product: x.product, })), } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить корзину' }) - } - }) + }), + ) - fastify.post('/api/me/cart/items', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.post( + '/api/me/cart/items', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const productId = String(request.body?.productId || '').trim() const qtyRaw = request.body?.qty @@ -46,14 +48,13 @@ export async function registerUserCartRoutes(fastify) { create: { userId, productId, qty: nextQty }, }) return reply.code(201).send({ item }) - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось добавить в корзину' }) - } - }) + }), + ) - fastify.patch('/api/me/cart/items/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.patch( + '/api/me/cart/items/:id', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const { id } = request.params const qtyRaw = request.body?.qty @@ -74,23 +75,19 @@ export async function registerUserCartRoutes(fastify) { const updated = await prisma.cartItem.update({ where: { id }, data: { qty: nextQty } }) return { item: updated } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось обновить количество' }) - } - }) + }), + ) - fastify.delete('/api/me/cart/items/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.delete( + '/api/me/cart/items/:id', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const { id } = request.params const existing = await prisma.cartItem.findFirst({ where: { id, userId } }) if (!existing) return reply.code(404).send({ error: 'Позиция корзины не найдена' }) await prisma.cartItem.delete({ where: { id } }) return reply.code(204).send() - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось удалить из корзины' }) - } - }) + }), + ) } diff --git a/server/src/routes/user-orders.js b/server/src/routes/user-orders.js index 2c2da0f..0a68e40 100644 --- a/server/src/routes/user-orders.js +++ b/server/src/routes/user-orders.js @@ -1,4 +1,5 @@ import { NOTIFICATION_EVENTS } from '../../../shared/constants/notification-events.js' +import { asyncHandler } from '../lib/async-handler.js' import { isDeliveryCarrier } from '../lib/delivery-carrier.js' import { prisma } from '../lib/prisma.js' @@ -176,8 +177,10 @@ export async function registerUserOrderRoutes(fastify) { return reply.code(201).send({ orderId: created.id }) }) - fastify.get('/api/me/orders', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.get( + '/api/me/orders', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const orders = await prisma.order.findMany({ where: { userId }, @@ -195,14 +198,13 @@ export async function registerUserOrderRoutes(fastify) { itemsCount: o.items.reduce((s, i) => s + i.qty, 0), })), } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить заказы' }) - } - }) + }), + ) - fastify.get('/api/me/orders/:id', { preHandler: [fastify.authenticate] }, async (request, reply) => { - try { + fastify.get( + '/api/me/orders/:id', + { preHandler: [fastify.authenticate] }, + asyncHandler(async (request, reply) => { const userId = request.user.sub const { id } = request.params const order = await prisma.order.findFirst({ @@ -211,11 +213,8 @@ export async function registerUserOrderRoutes(fastify) { }) if (!order) return reply.code(404).send({ error: 'Заказ не найден' }) return { item: order } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось загрузить заказ' }) - } - }) + }), + ) fastify.get( '/api/me/orders/:id/review-eligibility', @@ -260,25 +259,20 @@ export async function registerUserOrderRoutes(fastify) { fastify.post( '/api/me/orders/:id/confirm-received', { preHandler: [fastify.authenticate] }, - async (request, reply) => { - try { - const userId = request.user.sub - const { id } = request.params - const order = await prisma.order.findFirst({ where: { id, userId } }) - if (!order) return reply.code(404).send({ error: 'Заказ не найден' }) + asyncHandler(async (request, reply) => { + const userId = request.user.sub + const { id } = request.params + const order = await prisma.order.findFirst({ where: { id, userId } }) + if (!order) return reply.code(404).send({ error: 'Заказ не найден' }) - const okDelivery = order.deliveryType === 'delivery' && order.status === 'SHIPPED' - const okPickup = order.deliveryType === 'pickup' && order.status === 'READY_FOR_PICKUP' - if (!okDelivery && !okPickup) { - return reply.code(409).send({ error: 'Сейчас нельзя подтвердить получение заказа' }) - } - - await prisma.order.update({ where: { id }, data: { status: 'DONE' } }) - return { ok: true, status: 'DONE' } - } catch (err) { - request.log.error(err) - return reply.code(500).send({ error: 'Не удалось подтвердить получение' }) + const okDelivery = order.deliveryType === 'delivery' && order.status === 'SHIPPED' + const okPickup = order.deliveryType === 'pickup' && order.status === 'READY_FOR_PICKUP' + if (!okDelivery && !okPickup) { + return reply.code(409).send({ error: 'Сейчас нельзя подтвердить получение заказа' }) } - }, + + await prisma.order.update({ where: { id }, data: { status: 'DONE' } }) + return { ok: true, status: 'DONE' } + }), ) }