Intermediate 25 min read

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 {}
  1. public class InventoryException extends Exception {} — exactly Module 22's LibraryException pattern, 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;
}
  1. public void shipOrder(Id warehouseStockId, Decimal quantityShipped) { — the method.
  2. Warehouse_Stock__c stock = [ — queries the current stock.
  3. SELECT Id, Quantity_On_Hand__c FROM Warehouse_Stock__c WHERE Id = :warehouseStockId — the current value.
  4. ]; — closes the query.
  5. (blank line)
  6. if (stock.Quantity_On_Hand__c < quantityShipped) { — this upgrades the earlier lesson's return false; into a throw.
  7. throw new InventoryException( — with a specific, informative message.
  8. '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.
  9. ); — closes the throw.
  10. } — closes the if.
  11. (blank line)
  12. stock.Quantity_On_Hand__c -= quantityShipped; — only reached if there was enough stock.
  13. update stock; — saves the change.
  14. } — 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];
}
  1. public Warehouse_Stock__c getStockRecord(Id productId, String warehouseName) { — the method.
  2. List<Warehouse_Stock__c> matches = [ — queries by product and warehouse together.
  3. SELECT Id, Quantity_On_Hand__c — the fields needed.
  4. FROM Warehouse_Stock__c — the object.
  5. WHERE Product__c = :productId AND Warehouse_Name__c = :warehouseName — the exact combination.
  6. ]; — closes the query.
  7. (blank line)
  8. if (matches.isEmpty()) { — rather than assuming a Warehouse_Stock__c record always exists for any product/warehouse combination, checks matches.isEmpty() (Module 15) first.
  9. 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.
  10. } — closes the if.
  11. (blank line)
  12. return matches[0]; — safe now, since the empty case was already handled.
  13. } — 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(...); }

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Handle Errors Quiz

1. Why does getStockRecord check matches.isEmpty() before returning a result?

Log in to submit the quiz and save your score.

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.