Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions API-Documentation/express.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* Product API endpoints
*/
const productRouter = express.Router();

// Get all products with filtering and pagination
productRouter.get('/', async (req, res) => {
try {
const {
category,
minPrice,
maxPrice,
sort = 'createdAt',
order = 'desc',
page = 1,
limit = 20,
inStock
} = req.query;

// Build filter
const filter = {};

if (category) {
filter.category = category;
}

if (minPrice !== undefined || maxPrice !== undefined) {
filter.price = {};
if (minPrice !== undefined) filter.price.$gte = parseFloat(minPrice);
if (maxPrice !== undefined) filter.price.$lte = parseFloat(maxPrice);
}

if (inStock === 'true') {
filter.stockQuantity = { $gt: 0 };
}

// Calculate pagination
const skip = (parseInt(page) - 1) * parseInt(limit);

// Determine sort order
const sortOptions = {};
sortOptions[sort] = order === 'asc' ? 1 : -1;

// Execute query
const products = await ProductModel.find(filter)
.sort(sortOptions)
.skip(skip)
.limit(parseInt(limit));

// Get total count for pagination
const totalProducts = await ProductModel.countDocuments(filter);

return res.status(200).json({
products,
pagination: {
total: totalProducts,
page: parseInt(page),
limit: parseInt(limit),
pages: Math.ceil(totalProducts / parseInt(limit))
}
});
} catch (error) {
console.error('Error fetching products:', error);
return res.status(500).json({
error: 'Server error',
message: 'Failed to fetch products'
});
}
});

// Get product by ID
productRouter.get('/:productId', async (req, res) => {
try {
const { productId } = req.params;

const product = await ProductModel.findById(productId);

if (!product) {
return res.status(404).json({
error: 'Not found',
message: 'Product not found'
});
}

return res.status(200).json(product);
} catch (error) {
console.error('Error fetching product:', error);

// Check if error is invalid ObjectId format
if (error.name === 'CastError') {
return res.status(400).json({
error: 'Invalid ID',
message: 'Invalid product ID format'
});
}

return res.status(500).json({
error: 'Server error',
message: 'Failed to fetch product'
});
}
});

module.exports = productRouter;
Empty file.
Empty file added Error-Debug/dependancy.md
Empty file.
Empty file added Error-Debug/guide.md
Empty file.
Empty file added Error-Debug/indexOutOfBounds.js
Empty file.
55 changes: 55 additions & 0 deletions Error-Debug/learning_solutions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

# Proposed Fixes and Learning Points

## Solution

- Problem location: [use-cases/debug-errors-001/javascript/userList.js](use-cases/debug-errors-001/javascript/userList.js#L1-L200)
- Root cause: the code used a hardcoded loop `for (let i = 0; i < 5; i++)` and indexed into `users[i]`, which can be `undefined` when fewer than 5 users are returned.
- Code change (replace the unsafe loop with defensive iteration):

```javascript
// ❌ Unsafe original
for (let i = 0; i < 5; i++) {
const user = users[i];
const userName = user.name; // throws if user is undefined
...
}

// ✅ Safe replacement
if (!Array.isArray(users) || users.length === 0) {
userListElement.innerHTML = '<p>No users found.</p>';
return;
}

users.forEach(user => {
if (!user) return;
const userName = user.name || 'Unknown';
const userEmail = user.email || '';
// render user card
});
```

- Other small improvements included in the patch:
- Guarded against non-array or empty `users` input.
- Used safe property fallbacks (`user.name || 'Unknown'`).
- Skipped undefined entries to prevent crashes.

## Learning Points

- Always validate external data shapes before indexing or property access. Use `Array.isArray()` and check `.length`.
- Avoid magic numbers for iteration bounds. Use `array.length` or iteration helpers (`forEach`, `for...of`).
- Provide meaningful UX when data is empty (e.g., show "No users found.").
- Use safe property access patterns (`user?.name` or `user.name || 'Unknown'`) to prevent runtime exceptions.
- Add unit tests that cover edge cases: zero items, one item, many items, and malformed input (null/undefined/non-array).
- Consider linting (ESLint) and light static typing (JSDoc or TypeScript) to catch these mistakes early.

## Suggested Tests & Next Steps

- Add a unit test (Jest + JSDOM) that calls `renderUserList([])` and asserts the DOM contains "No users found.".
- Add tests for `renderUserList([null, {name: 'A'}])` to ensure undefined entries are skipped.
- Search the repo for other hardcoded loops that index external data and apply similar defensive checks.

---

Document created to record the proposed change and to help prevent similar errors in the future.

Empty file added Error-Debug/rootCause.md
Empty file.
Empty file.
Empty file.
Empty file added use-cases/task-manager/FAQ.md
Empty file.
Empty file.
Loading