feat: setup basic error handling on server

This commit is contained in:
Henry
2024-07-30 22:36:39 +01:00
parent 9931a585a5
commit 2033f37e72
7 changed files with 190 additions and 34 deletions

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import {
createTRPCRouter,
@@ -12,9 +13,15 @@ import * as userRepo from "~/server/db/repository/user.repo";
export const authRouter = createTRPCRouter({
getUser: protectedProcedure.query(async ({ ctx }) => {
if (!ctx.user?.id) return;
const userId = ctx.user?.id;
const result = await userRepo.getById(ctx.db, ctx.user.id);
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await userRepo.getById(ctx.db, userId);
return result;
}),
@@ -33,7 +40,11 @@ export const authRouter = createTRPCRouter({
loginWithOAuth: publicProcedure
.input(z.object({ provider: z.string() }))
.mutation(async ({ ctx, input }) => {
if (input.provider !== "google") return null;
if (input.provider !== "google")
throw new TRPCError({
message: `Unsupported OAuth provider: ${input.provider}`,
code: "BAD_REQUEST",
});
const { data } = await ctx.db.auth.signInWithOAuth({
provider: "google",

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
@@ -16,7 +17,11 @@ export const boardRouter = createTRPCRouter({
input.workspacePublicId,
);
if (!workspace) return;
if (!workspace)
throw new TRPCError({
message: `Workspace with public ID ${input.workspacePublicId} not found`,
code: "NOT_FOUND",
});
const result = boardRepo.getAllByWorkspaceId(ctx.db, workspace.id);
@@ -39,14 +44,22 @@ export const boardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const workspace = await workspaceRepo.getByPublicId(
ctx.db,
input.workspacePublicId,
);
if (!workspace) return;
if (!workspace)
throw new TRPCError({
message: `Workspace with public ID ${input.workspacePublicId} not found`,
code: "NOT_FOUND",
});
const result = await boardRepo.create(ctx.db, {
name: input.name,
@@ -80,11 +93,22 @@ export const boardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const board = await boardRepo.getWithListIdsByPublicId(
ctx.db,
input.boardPublicId,
);
if (!board || !userId) return;
if (!board)
throw new TRPCError({
message: `Board with public ID ${input.boardPublicId} not found`,
code: "NOT_FOUND",
});
const listIds = board.lists.map((list) => list.id);

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
@@ -21,14 +22,22 @@ export const cardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const list = await listRepo.getWithCardsByPublicId(
ctx.db,
input.listPublicId,
);
if (!list?.id) return;
if (!list?.id)
throw new TRPCError({
message: `List with public ID ${input.listPublicId} not found`,
code: "NOT_FOUND",
});
const lastCard = list.cards.length && list.cards[0];
@@ -60,7 +69,11 @@ export const cardRouter = createTRPCRouter({
input.labelPublicIds,
);
if (!labels?.length) return;
if (!labels?.length)
throw new TRPCError({
message: `Labels with public IDs ${input.labelPublicIds} not found`,
code: "NOT_FOUND",
});
const labelsInsert = labels.map((label) => ({
cardId: newCardId,
@@ -76,7 +89,11 @@ export const cardRouter = createTRPCRouter({
input.memberPublicIds,
);
if (!members?.length) return;
if (!members?.length)
throw new TRPCError({
message: `Members with public IDs ${input.memberPublicIds} not found`,
code: "NOT_FOUND",
});
const membersInsert = members.map((member) => ({
cardId: newCardId,
@@ -101,12 +118,26 @@ export const cardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const label = await labelRepo.getByPublicId(ctx.db, input.labelPublicId);
if (!card || !label) return;
if (!card)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
if (!label)
throw new TRPCError({
message: `Label with public ID ${input.labelPublicId} not found`,
code: "NOT_FOUND",
});
const cardLabelIds = { cardId: card.id, labelId: label.id };
@@ -135,7 +166,11 @@ export const cardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getByPublicId(ctx.db, input.cardPublicId);
const member = await workspaceRepo.getMemberByPublicId(
@@ -143,7 +178,17 @@ export const cardRouter = createTRPCRouter({
input.workspaceMemberPublicId,
);
if (!card || !member) return;
if (!card)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
if (!member)
throw new TRPCError({
message: `Member with public ID ${input.workspaceMemberPublicId} not found`,
code: "NOT_FOUND",
});
const cardMemberIds = { cardId: card.id, memberId: member.id };
@@ -183,7 +228,11 @@ export const cardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = cardRepo.update(
ctx.db,
@@ -202,14 +251,22 @@ export const cardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getCardWithListByPublicId(
ctx.db,
input.cardPublicId,
);
if (!card ?? !card?.list?.id) return;
if (!card ?? !card?.list?.id)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
const deletedAt = new Date().toISOString();
@@ -235,14 +292,22 @@ export const cardRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getCardWithListByPublicId(
ctx.db,
input.cardId,
);
if (!card) return;
if (!card || !card.list)
throw new TRPCError({
message: `Card with public ID ${input.cardId} not found`,
code: "NOT_FOUND",
});
const currentList = card.list;
const currentIndex = card.index;
@@ -254,7 +319,11 @@ export const cardRouter = createTRPCRouter({
input.newListId,
);
if (!newList) return;
if (!newList)
throw new TRPCError({
message: `List with public ID ${input.newListId} not found`,
code: "NOT_FOUND",
});
if (newIndex === undefined) {
const lastCardIndex = newList.cards.length
@@ -264,8 +333,6 @@ export const cardRouter = createTRPCRouter({
newIndex = lastCardIndex !== undefined ? lastCardIndex + 1 : 0;
}
if (!currentList?.id || !newList.id) return;
const result = await cardRepo.reorder(ctx.db, {
currentListId: currentList.id,
newListId: newList.id,

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { generateUID } from "~/utils/generateUID";
@@ -89,7 +90,11 @@ export const importRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const newImport = await importRepo.create(ctx.db, {
source: "trello",
@@ -105,7 +110,11 @@ export const importRouter = createTRPCRouter({
input.workspacePublicId,
);
if (!workspace) return;
if (!workspace)
throw new TRPCError({
message: `Workspace with public ID ${input.workspacePublicId} not found`,
code: "NOT_FOUND",
});
for (const boardId of input.boardIds) {
const response = await fetch(
@@ -135,7 +144,11 @@ export const importRouter = createTRPCRouter({
const newBoardId = newBoard?.id;
if (!newBoardId) return;
if (!newBoardId)
throw new TRPCError({
message: "Failed to create new board",
code: "INTERNAL_SERVER_ERROR",
});
let listIndex = 0;

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
@@ -17,14 +18,22 @@ export const labelRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getCardWithListByPublicId(
ctx.db,
input.cardPublicId,
);
if (!card?.list) return;
if (!card?.list)
throw new TRPCError({
message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND",
});
const result = await labelRepo.create(ctx.db, {
name: input.name,

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
@@ -17,14 +18,22 @@ export const listRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const board = await boardRepo.getWithLatestListIndexByPublicId(
ctx.db,
input.boardPublicId,
);
if (!board) return;
if (!board)
throw new TRPCError({
message: `Board with public ID ${input.boardPublicId} not found`,
code: "NOT_FOUND",
});
const latestListIndex = board.lists[0]?.index;
@@ -49,7 +58,11 @@ export const listRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const list = await listRepo.getByPublicId(ctx.db, input.listId);
if (!list) return;
if (!list)
throw new TRPCError({
message: `List with public ID ${input.listId} not found`,
code: "NOT_FOUND",
});
const result = listRepo.reorder(ctx.db, {
boardPublicId: list.boardId,
@@ -69,9 +82,19 @@ export const listRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const list = await listRepo.getByPublicId(ctx.db, input.listPublicId);
if (!list || !userId) return;
if (!list)
throw new TRPCError({
message: `List with public ID ${input.listPublicId} not found`,
code: "NOT_FOUND",
});
const deletedAt = new Date().toISOString();

View File

@@ -1,4 +1,5 @@
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import * as workspaceRepo from "~/server/db/repository/workspace.repo";
@@ -7,7 +8,11 @@ export const workspaceRouter = createTRPCRouter({
all: protectedProcedure.query(async ({ ctx }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await workspaceRepo.getAllByUserId(ctx.db, userId);
@@ -32,7 +37,11 @@ export const workspaceRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId) return;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await workspaceRepo.create(ctx.db, {
name: input.name,