Handle Errors
By the end of this lesson, you'll be able to:
- Reject a shipment that would push stock negative
- Guard against receiving a shipment for a product with no existing stock record
- Use a custom exception for a genuinely invalid inventory operation
Prerequisites: "Search Across Warehouses (SOSL)"
A custom exception for inventory errors
public class InventoryException extends Exception {}
public class InventoryException extends Exception {}— exactly Module 22'sLibraryExceptionpattern, reused for a different domain — a dedicated exception type lets inventory-specific failures be caught distinctly from generic Apex exceptions.
Rejecting a shipment that would go negative
public void shipOrder(Id warehouseStockId, Decimal quantityShipped) {
Warehouse_Stock__c stock = [
SELECT Id, Quantity_On_Hand__c FROM Warehouse_Stock__c WHERE Id = :warehouseStockId
];
if (stock.Quantity_On_Hand__c < quantityShipped) {
throw new InventoryException(
'Cannot ship ' + quantityShipped + ' units — only ' + stock.Quantity_On_Hand__c + ' available.'
);
}
stock.Quantity_On_Hand__c -= quantityShipped;
update stock;
}
public void shipOrder(Id warehouseStockId, Decimal quantityShipped) {— the method.Warehouse_Stock__c stock = [— queries the current stock.SELECT Id, Quantity_On_Hand__c FROM Warehouse_Stock__c WHERE Id = :warehouseStockId— the current value.];— closes the query.- (blank line)
if (stock.Quantity_On_Hand__c < quantityShipped) {— this upgrades the earlier lesson'sreturn false;into athrow.throw new InventoryException(— with a specific, informative message.'Cannot ship ' + quantityShipped + ' units — only ' + stock.Quantity_On_Hand__c + ' available.'— a genuine business-rule violation now stops the operation loudly rather than just signaling failure through a return value.);— closes thethrow.}— closes theif.- (blank line)
stock.Quantity_On_Hand__c -= quantityShipped;— only reached if there was enough stock.update stock;— saves the change.}— closes the method.
Guarding against a missing stock record
public Warehouse_Stock__c getStockRecord(Id productId, String warehouseName) {
List<Warehouse_Stock__c> matches = [
SELECT Id, Quantity_On_Hand__c
FROM Warehouse_Stock__c
WHERE Product__c = :productId AND Warehouse_Name__c = :warehouseName
];
if (matches.isEmpty()) {
throw new InventoryException('No stock record exists for this product at this warehouse.');
}
return matches[0];
}
public Warehouse_Stock__c getStockRecord(Id productId, String warehouseName) {— the method.List<Warehouse_Stock__c> matches = [— queries by product and warehouse together.SELECT Id, Quantity_On_Hand__c— the fields needed.FROM Warehouse_Stock__c— the object.WHERE Product__c = :productId AND Warehouse_Name__c = :warehouseName— the exact combination.];— closes the query.- (blank line)
if (matches.isEmpty()) {— rather than assuming aWarehouse_Stock__crecord always exists for any product/warehouse combination, checksmatches.isEmpty()(Module 15) first.throw new InventoryException('No stock record exists for this product at this warehouse.');— receiving stock for a genuinely new warehouse should create a fresh record, not silently fail while looking for one that was never set up.}— closes theif.- (blank line)
return matches[0];— safe now, since the empty case was already handled.}— closes the method.
Exercise
Given a Warehouse_Stock__c already queried, write a guard that throws InventoryException if Quantity_On_Hand__c is less than a requested shipQuantity.
Show hint
if (stock.Quantity_On_Hand__c < shipQuantity) { throw new InventoryException(...); }
Handle Errors Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
This lesson hardens InventoryService against two real misuses: shipping more stock than exists, and adjusting stock for a product/warehouse combination that was never set up.