refactor(inventory): propagate UserError for predictable failures

This commit is contained in:
syntaxbullet
2025-12-22 12:55:46 +01:00
parent 216189b0a4
commit 4a0a2a5878

View File

@@ -4,6 +4,7 @@ import { DrizzleClient } from "@/lib/DrizzleClient";
import { economyService } from "@/modules/economy/economy.service"; import { economyService } from "@/modules/economy/economy.service";
import { levelingService } from "@/modules/leveling/leveling.service"; import { levelingService } from "@/modules/leveling/leveling.service";
import { config } from "@/lib/config"; import { config } from "@/lib/config";
import { UserError } from "@/lib/errors";
import { withTransaction } from "@/lib/db"; import { withTransaction } from "@/lib/db";
import type { Transaction, ItemUsageData } from "@/lib/types"; import type { Transaction, ItemUsageData } from "@/lib/types";
@@ -28,7 +29,7 @@ export const inventoryService = {
if (existing) { if (existing) {
const newQuantity = (existing.quantity ?? 0n) + quantity; const newQuantity = (existing.quantity ?? 0n) + quantity;
if (newQuantity > config.inventory.maxStackSize) { if (newQuantity > config.inventory.maxStackSize) {
throw new Error(`Cannot exceed max stack size of ${config.inventory.maxStackSize}`); throw new UserError(`Cannot exceed max stack size of ${config.inventory.maxStackSize}`);
} }
const [entry] = await txFn.update(inventory) const [entry] = await txFn.update(inventory)
@@ -49,11 +50,11 @@ export const inventoryService = {
.where(eq(inventory.userId, BigInt(userId))); .where(eq(inventory.userId, BigInt(userId)));
if (inventoryCount && inventoryCount.count >= config.inventory.maxSlots) { if (inventoryCount && inventoryCount.count >= config.inventory.maxSlots) {
throw new Error(`Inventory full (Max ${config.inventory.maxSlots} slots)`); throw new UserError(`Inventory full (Max ${config.inventory.maxSlots} slots)`);
} }
if (quantity > config.inventory.maxStackSize) { if (quantity > config.inventory.maxStackSize) {
throw new Error(`Cannot exceed max stack size of ${config.inventory.maxStackSize}`); throw new UserError(`Cannot exceed max stack size of ${config.inventory.maxStackSize}`);
} }
const [entry] = await txFn.insert(inventory) const [entry] = await txFn.insert(inventory)
@@ -78,7 +79,7 @@ export const inventoryService = {
}); });
if (!existing || (existing.quantity ?? 0n) < quantity) { if (!existing || (existing.quantity ?? 0n) < quantity) {
throw new Error("Insufficient item quantity"); throw new UserError("Insufficient item quantity");
} }
if ((existing.quantity ?? 0n) === quantity) { if ((existing.quantity ?? 0n) === quantity) {
@@ -119,8 +120,8 @@ export const inventoryService = {
where: eq(items.id, itemId), where: eq(items.id, itemId),
}); });
if (!item) throw new Error("Item not found"); if (!item) throw new UserError("Item not found");
if (!item.price) throw new Error("Item is not for sale"); if (!item.price) throw new UserError("Item is not for sale");
const totalPrice = item.price * quantity; const totalPrice = item.price * quantity;
@@ -151,14 +152,14 @@ export const inventoryService = {
}); });
if (!entry || (entry.quantity ?? 0n) < 1n) { if (!entry || (entry.quantity ?? 0n) < 1n) {
throw new Error("You do not own this item."); throw new UserError("You do not own this item.");
} }
const item = entry.item; const item = entry.item;
const usageData = item.usageData as ItemUsageData | null; const usageData = item.usageData as ItemUsageData | null;
if (!usageData || !usageData.effects || usageData.effects.length === 0) { if (!usageData || !usageData.effects || usageData.effects.length === 0) {
throw new Error("This item cannot be used."); throw new UserError("This item cannot be used.");
} }
const results: string[] = []; const results: string[] = [];