feat: setup basic error handling on server
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user