refactor: use safe request-scoped backend error logging
This commit is contained in:
parent
e2e9ec9eb4
commit
9cb0ac19e5
@ -1,6 +1,7 @@
|
||||
const householdModel = require("../models/household.model");
|
||||
const { sendError } = require("../utils/http");
|
||||
const { inviteCodeLast4, safeErrorMessage } = require("../utils/redaction");
|
||||
const { inviteCodeLast4 } = require("../utils/redaction");
|
||||
const { logError } = require("../utils/logger");
|
||||
|
||||
// Get all households user belongs to
|
||||
exports.getUserHouseholds = async (req, res) => {
|
||||
@ -8,7 +9,7 @@ exports.getUserHouseholds = async (req, res) => {
|
||||
const households = await householdModel.getUserHouseholds(req.user.id);
|
||||
res.json(households);
|
||||
} catch (error) {
|
||||
console.error("Get user households error:", error);
|
||||
logError(req, "households.getUserHouseholds", error);
|
||||
sendError(res, 500, "Failed to fetch households");
|
||||
}
|
||||
};
|
||||
@ -27,7 +28,7 @@ exports.getHousehold = async (req, res) => {
|
||||
|
||||
res.json(household);
|
||||
} catch (error) {
|
||||
console.error("Get household error:", error);
|
||||
logError(req, "households.getHousehold", error);
|
||||
sendError(res, 500, "Failed to fetch household");
|
||||
}
|
||||
};
|
||||
@ -55,7 +56,7 @@ exports.createHousehold = async (req, res) => {
|
||||
household
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Create household error:", error);
|
||||
logError(req, "households.createHousehold", error);
|
||||
sendError(res, 500, "Failed to create household");
|
||||
}
|
||||
};
|
||||
@ -83,7 +84,7 @@ exports.updateHousehold = async (req, res) => {
|
||||
household
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Update household error:", error);
|
||||
logError(req, "households.updateHousehold", error);
|
||||
sendError(res, 500, "Failed to update household");
|
||||
}
|
||||
};
|
||||
@ -94,7 +95,7 @@ exports.deleteHousehold = async (req, res) => {
|
||||
await householdModel.deleteHousehold(req.params.householdId);
|
||||
res.json({ message: "Household deleted successfully" });
|
||||
} catch (error) {
|
||||
console.error("Delete household error:", error);
|
||||
logError(req, "households.deleteHousehold", error);
|
||||
sendError(res, 500, "Failed to delete household");
|
||||
}
|
||||
};
|
||||
@ -108,11 +109,9 @@ exports.refreshInviteCode = async (req, res) => {
|
||||
household
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Refresh invite code error request_id=${req.request_id} invite_last4=${inviteCodeLast4(
|
||||
req.body?.inviteCode
|
||||
)} message=${safeErrorMessage(error)}`
|
||||
);
|
||||
logError(req, "households.refreshInviteCode", error, {
|
||||
invite_last4: inviteCodeLast4(req.body?.inviteCode),
|
||||
});
|
||||
sendError(res, 500, "Failed to refresh invite code");
|
||||
}
|
||||
};
|
||||
@ -144,11 +143,7 @@ exports.joinHousehold = async (req, res) => {
|
||||
household: { id: result.id, name: result.name }
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Join household error request_id=${req.request_id} invite_last4=${inviteLast4} message=${safeErrorMessage(
|
||||
error
|
||||
)}`
|
||||
);
|
||||
logError(req, "households.joinHousehold", error, { invite_last4: inviteLast4 });
|
||||
sendError(res, 500, "Failed to join household");
|
||||
}
|
||||
};
|
||||
@ -159,7 +154,7 @@ exports.getMembers = async (req, res) => {
|
||||
const members = await householdModel.getHouseholdMembers(req.params.householdId);
|
||||
res.json(members);
|
||||
} catch (error) {
|
||||
console.error("Get members error:", error);
|
||||
logError(req, "households.getMembers", error);
|
||||
sendError(res, 500, "Failed to fetch members");
|
||||
}
|
||||
};
|
||||
@ -190,7 +185,7 @@ exports.updateMemberRole = async (req, res) => {
|
||||
member: updated
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Update member role error:", error);
|
||||
logError(req, "households.updateMemberRole", error);
|
||||
sendError(res, 500, "Failed to update member role");
|
||||
}
|
||||
};
|
||||
@ -210,7 +205,7 @@ exports.removeMember = async (req, res) => {
|
||||
|
||||
res.json({ message: "Member removed successfully" });
|
||||
} catch (error) {
|
||||
console.error("Remove member error:", error);
|
||||
logError(req, "households.removeMember", error);
|
||||
sendError(res, 500, "Failed to remove member");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const List = require("../models/list.model");
|
||||
const { isValidItemType, isValidItemGroup, isValidZone } = require("../constants/classifications");
|
||||
const { sendError } = require("../utils/http");
|
||||
const { logError } = require("../utils/logger");
|
||||
|
||||
|
||||
exports.getList = async (req, res) => {
|
||||
@ -114,7 +115,7 @@ exports.updateItemWithClassification = async (req, res) => {
|
||||
|
||||
res.json({ message: "Item updated successfully" });
|
||||
} catch (error) {
|
||||
console.error("Error updating item with classification:", error);
|
||||
logError(req, "listsLegacy.updateItemWithClassification", error);
|
||||
sendError(res, 500, "Failed to update item");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const List = require("../models/list.model.v2");
|
||||
const { isValidItemType, isValidItemGroup, isValidZone } = require("../constants/classifications");
|
||||
const { sendError } = require("../utils/http");
|
||||
const { logError } = require("../utils/logger");
|
||||
|
||||
/**
|
||||
* Get list items for household and store
|
||||
@ -12,7 +13,7 @@ exports.getList = async (req, res) => {
|
||||
const items = await List.getHouseholdStoreList(householdId, storeId);
|
||||
res.json({ items });
|
||||
} catch (error) {
|
||||
console.error("Error getting list:", error);
|
||||
logError(req, "listsV2.getList", error);
|
||||
sendError(res, 500, "Failed to get list");
|
||||
}
|
||||
};
|
||||
@ -37,7 +38,7 @@ exports.getItemByName = async (req, res) => {
|
||||
|
||||
res.json(item);
|
||||
} catch (error) {
|
||||
console.error("Error getting item:", error);
|
||||
logError(req, "listsV2.getItemByName", error);
|
||||
sendError(res, 500, "Failed to get item");
|
||||
}
|
||||
};
|
||||
@ -84,7 +85,7 @@ exports.addItem = async (req, res) => {
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error adding item:", error);
|
||||
logError(req, "listsV2.addItem", error);
|
||||
sendError(res, 500, "Failed to add item");
|
||||
}
|
||||
};
|
||||
@ -109,7 +110,7 @@ exports.markBought = async (req, res) => {
|
||||
|
||||
res.json({ message: bought ? "Item marked as bought" : "Item unmarked" });
|
||||
} catch (error) {
|
||||
console.error("Error marking bought:", error);
|
||||
logError(req, "listsV2.markBought", error);
|
||||
sendError(res, 500, "Failed to update item");
|
||||
}
|
||||
};
|
||||
@ -146,7 +147,7 @@ exports.updateItem = async (req, res) => {
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error updating item:", error);
|
||||
logError(req, "listsV2.updateItem", error);
|
||||
sendError(res, 500, "Failed to update item");
|
||||
}
|
||||
};
|
||||
@ -174,7 +175,7 @@ exports.deleteItem = async (req, res) => {
|
||||
|
||||
res.json({ message: "Item deleted" });
|
||||
} catch (error) {
|
||||
console.error("Error deleting item:", error);
|
||||
logError(req, "listsV2.deleteItem", error);
|
||||
sendError(res, 500, "Failed to delete item");
|
||||
}
|
||||
};
|
||||
@ -191,7 +192,7 @@ exports.getSuggestions = async (req, res) => {
|
||||
const suggestions = await List.getSuggestions(query || "", householdId, storeId);
|
||||
res.json(suggestions);
|
||||
} catch (error) {
|
||||
console.error("Error getting suggestions:", error);
|
||||
logError(req, "listsV2.getSuggestions", error);
|
||||
sendError(res, 500, "Failed to get suggestions");
|
||||
}
|
||||
};
|
||||
@ -206,7 +207,7 @@ exports.getRecentlyBought = async (req, res) => {
|
||||
const items = await List.getRecentlyBoughtItems(householdId, storeId);
|
||||
res.json(items);
|
||||
} catch (error) {
|
||||
console.error("Error getting recent items:", error);
|
||||
logError(req, "listsV2.getRecentlyBought", error);
|
||||
sendError(res, 500, "Failed to get recent items");
|
||||
}
|
||||
};
|
||||
@ -233,7 +234,7 @@ exports.getClassification = async (req, res) => {
|
||||
const classification = await List.getClassification(householdId, item.item_id);
|
||||
res.json({ classification });
|
||||
} catch (error) {
|
||||
console.error("Error getting classification:", error);
|
||||
logError(req, "listsV2.getClassification", error);
|
||||
sendError(res, 500, "Failed to get classification");
|
||||
}
|
||||
};
|
||||
@ -290,7 +291,7 @@ exports.setClassification = async (req, res) => {
|
||||
|
||||
res.json({ message: "Classification set", classification });
|
||||
} catch (error) {
|
||||
console.error("Error setting classification:", error);
|
||||
logError(req, "listsV2.setClassification", error);
|
||||
sendError(res, 500, "Failed to set classification");
|
||||
}
|
||||
};
|
||||
@ -318,7 +319,7 @@ exports.updateItemImage = async (req, res) => {
|
||||
|
||||
res.json({ message: "Image updated successfully" });
|
||||
} catch (error) {
|
||||
console.error("Error updating image:", error);
|
||||
logError(req, "listsV2.updateItemImage", error);
|
||||
sendError(res, 500, "Failed to update image");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
const storeModel = require("../models/store.model");
|
||||
const { sendError } = require("../utils/http");
|
||||
const { logError } = require("../utils/logger");
|
||||
|
||||
// Get all available stores
|
||||
exports.getAllStores = async (req, res) => {
|
||||
@ -7,7 +8,7 @@ exports.getAllStores = async (req, res) => {
|
||||
const stores = await storeModel.getAllStores();
|
||||
res.json(stores);
|
||||
} catch (error) {
|
||||
console.error("Get all stores error:", error);
|
||||
logError(req, "stores.getAllStores", error);
|
||||
sendError(res, 500, "Failed to fetch stores");
|
||||
}
|
||||
};
|
||||
@ -18,7 +19,7 @@ exports.getHouseholdStores = async (req, res) => {
|
||||
const stores = await storeModel.getHouseholdStores(req.params.householdId);
|
||||
res.json(stores);
|
||||
} catch (error) {
|
||||
console.error("Get household stores error:", error);
|
||||
logError(req, "stores.getHouseholdStores", error);
|
||||
sendError(res, 500, "Failed to fetch household stores");
|
||||
}
|
||||
};
|
||||
@ -48,7 +49,7 @@ exports.addStoreToHousehold = async (req, res) => {
|
||||
store
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Add store to household error:", error);
|
||||
logError(req, "stores.addStoreToHousehold", error);
|
||||
sendError(res, 500, "Failed to add store to household");
|
||||
}
|
||||
};
|
||||
@ -63,7 +64,7 @@ exports.removeStoreFromHousehold = async (req, res) => {
|
||||
|
||||
res.json({ message: "Store removed from household successfully" });
|
||||
} catch (error) {
|
||||
console.error("Remove store from household error:", error);
|
||||
logError(req, "stores.removeStoreFromHousehold", error);
|
||||
sendError(res, 500, "Failed to remove store from household");
|
||||
}
|
||||
};
|
||||
@ -78,7 +79,7 @@ exports.setDefaultStore = async (req, res) => {
|
||||
|
||||
res.json({ message: "Default store updated successfully" });
|
||||
} catch (error) {
|
||||
console.error("Set default store error:", error);
|
||||
logError(req, "stores.setDefaultStore", error);
|
||||
sendError(res, 500, "Failed to set default store");
|
||||
}
|
||||
};
|
||||
@ -99,7 +100,7 @@ exports.createStore = async (req, res) => {
|
||||
store
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Create store error:", error);
|
||||
logError(req, "stores.createStore", error);
|
||||
if (error.code === '23505') { // Unique violation
|
||||
return sendError(res, 400, "Store with this name already exists");
|
||||
}
|
||||
@ -126,7 +127,7 @@ exports.updateStore = async (req, res) => {
|
||||
store
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Update store error:", error);
|
||||
logError(req, "stores.updateStore", error);
|
||||
sendError(res, 500, "Failed to update store");
|
||||
}
|
||||
};
|
||||
@ -137,7 +138,7 @@ exports.deleteStore = async (req, res) => {
|
||||
await storeModel.deleteStore(req.params.storeId);
|
||||
res.json({ message: "Store deleted successfully" });
|
||||
} catch (error) {
|
||||
console.error("Delete store error:", error);
|
||||
logError(req, "stores.deleteStore", error);
|
||||
if (error.message.includes('in use')) {
|
||||
return sendError(res, 400, error.message);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const User = require("../models/user.model");
|
||||
const bcrypt = require("bcryptjs");
|
||||
const { sendError } = require("../utils/http");
|
||||
const { logError } = require("../utils/logger");
|
||||
|
||||
exports.test = async (req, res) => {
|
||||
console.log("User route is working");
|
||||
@ -27,6 +28,7 @@ exports.updateUserRole = async (req, res) => {
|
||||
|
||||
res.json({ message: "Role updated", id, role });
|
||||
} catch (err) {
|
||||
logError(req, "users.updateUserRole", err);
|
||||
sendError(res, 500, "Failed to update role");
|
||||
}
|
||||
};
|
||||
@ -42,6 +44,7 @@ exports.deleteUser = async (req, res) => {
|
||||
|
||||
res.json({ message: "User deleted", id });
|
||||
} catch (err) {
|
||||
logError(req, "users.deleteUser", err);
|
||||
sendError(res, 500, "Failed to delete user");
|
||||
}
|
||||
};
|
||||
@ -63,7 +66,7 @@ exports.getCurrentUser = async (req, res) => {
|
||||
|
||||
res.json(user);
|
||||
} catch (err) {
|
||||
console.error("Error getting current user:", err);
|
||||
logError(req, "users.getCurrentUser", err);
|
||||
sendError(res, 500, "Failed to get user profile");
|
||||
}
|
||||
};
|
||||
@ -89,7 +92,7 @@ exports.updateCurrentUser = async (req, res) => {
|
||||
|
||||
res.json({ message: "Profile updated successfully", user: updated });
|
||||
} catch (err) {
|
||||
console.error("Error updating user profile:", err);
|
||||
logError(req, "users.updateCurrentUser", err);
|
||||
sendError(res, 500, "Failed to update profile");
|
||||
}
|
||||
};
|
||||
@ -131,7 +134,7 @@ exports.changePassword = async (req, res) => {
|
||||
|
||||
res.json({ message: "Password changed successfully" });
|
||||
} catch (err) {
|
||||
console.error("Error changing password:", err);
|
||||
logError(req, "users.changePassword", err);
|
||||
sendError(res, 500, "Failed to change password");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
const householdModel = require("../models/household.model");
|
||||
const { sendError } = require("../utils/http");
|
||||
const { logError } = require("../utils/logger");
|
||||
|
||||
// Middleware to check if user belongs to household
|
||||
exports.householdAccess = async (req, res, next) => {
|
||||
@ -29,7 +30,7 @@ exports.householdAccess = async (req, res, next) => {
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error("Household access check error:", error);
|
||||
logError(req, "middleware.householdAccess", error);
|
||||
sendError(res, 500, "Server error checking household access");
|
||||
}
|
||||
};
|
||||
@ -84,7 +85,7 @@ exports.storeAccess = async (req, res, next) => {
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error("Store access check error:", error);
|
||||
logError(req, "middleware.storeAccess", error);
|
||||
sendError(res, 500, "Server error checking store access");
|
||||
}
|
||||
};
|
||||
|
||||
20
backend/utils/logger.js
Normal file
20
backend/utils/logger.js
Normal file
@ -0,0 +1,20 @@
|
||||
const { safeErrorMessage } = require("./redaction");
|
||||
|
||||
function formatExtra(extra = {}) {
|
||||
return Object.entries(extra)
|
||||
.filter(([, value]) => value !== undefined && value !== null && value !== "")
|
||||
.map(([key, value]) => `${key}=${String(value)}`)
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
function logError(req, context, error, extra = {}) {
|
||||
const requestId = req?.request_id || "unknown";
|
||||
const message = safeErrorMessage(error);
|
||||
const extraText = formatExtra(extra);
|
||||
const suffix = extraText ? ` ${extraText}` : "";
|
||||
console.error(`[${context}] request_id=${requestId} message=${message}${suffix}`);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
logError,
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user