7.09 Nested try-catch, Exception Slicing during Rethrow & RTOS Fault Escalation
💻 1. Annotated Source Code
#include <iostream> #include <stdexcept> using namespace std; void processPositive(int num); void doSomething(int num); int main() { int input; try { cout << "Enter a number to process!" << endl; cin >> input; doSomething(input); cout << "Yay! main was able to completely process the num!" << endl; } catch (const invalid_argument& err) { cout << "main says there is an error!" << endl; cout << err.what() << endl; } catch (const out_of_range& err) { cout << "main says the number is too big!" << endl; cout << err.what() << endl; } return 0; } void processPositive(int num) { cout << "Welcome to the positive integer processor!" << endl; if (num > 100) { cout << "processPositive says the number is too big!" << endl; throw out_of_range("Number cannot be greater than 100"); } else if (num >= 0) { cout << "Good job! You passed in a positive num to processPositive!" << endl; } else { throw invalid_argument("Negative number passed in!"); } } void doSomething(int num) { try { processPositive(num); cout << "Yay! doSomething could process the num!" << endl; } catch (const invalid_argument& err) { cout << "doSomething says there is a problem!" << endl; throw; } catch (const out_of_range& err) { cout << "doSomething says the number is too big!" << endl; throw; } }
📐 2. Architecture & UML Class Model
📚 3. Core C++ Concepts Deep-Dive
1. Correct Rethrowing Syntax (throw; vs throw e;)
When rethrowing an active exception, always use throw; with no operand. Using throw e; constructs a new exception copy of type e, causing object slicing if e is a base class reference.
2. Multi-Tier Error Propagation
A low-level function catches an error to perform localized cleanup (e.g. closing a file or releasing a lock), and then rethrows it to let higher-level orchestration logic handle user notification or system recovery.
⚡ 4. Embedded Systems & Hardware Reality
1. RTOS Hierarchical Fault Escalation
In multi-tasking Real-Time Operating Systems (e.g. FreeRTOS, Zephyr), errors escalate through formal levels:
- Level 1 (Task Level): Retry transient peripheral read (e.g. I2C retry).
- Level 2 (Supervisor Level): Restart malfunctioning task and re-initialize peripheral driver.
- Level 3 (System Level): Log error telemetry to Non-Volatile Backup SRAM (NVRAM) and trigger a controlled software reset via NVIC.
2. Non-Volatile Black-Box Logging
Safety-critical firmware maintains a circular crash log in battery-backed SRAM or EEPROM to preserve stack frames and fault status registers across watchdog resets for forensic diagnosis.
💡 5. Production-Ready Embedded Refactoring
Here is an embedded multi-tier fault escalation and telemetry logging architecture:
#include <cstdint> enum class EscalationLevel : uint8_t { TaskHandled = 0, TaskRestart, SystemResetSafeMode }; struct FaultLogEntry { uint32_t timestamp_ms; uint16_t error_code; uint8_t task_id; uint8_t severity; }; class SystemFaultSupervisor { public: static EscalationLevel record_fault(uint8_t task_id, uint16_t error_code, uint8_t retries_exhausted) noexcept { // 1. Write to Non-Volatile Backup SRAM log_to_nvram({/* timestamp */ 123456, error_code, task_id, retries_exhausted}); // 2. Determine escalation tier if (retries_exhausted < 3) { return EscalationLevel::TaskHandled; } else if (retries_exhausted < 5) { return EscalationLevel::TaskRestart; } else { // Escalate to controlled MCU Reset trigger_system_reset(); return EscalationLevel::SystemResetSafeMode; } } private: static void log_to_nvram(const FaultLogEntry& entry) noexcept { // Write to battery-backed register bank } static void trigger_system_reset() noexcept { // NVIC_SystemReset(); (ARM Cortex-M CMSIS call) } };
📝 Knowledge Verification Quiz
Test your understanding of the C++ concepts and embedded microcontroller trade-offs covered in this guide. Click any option for instant feedback.
throw; re-raises the active exception retaining its dynamic polymorphic type. throw e; copies the base-type slice, slicing away any derived class data and custom what() logic.
NVIC_SystemReset() sets the SYSRESETREQ bit in the Application Interrupt and Reset Control Register (AIRCR), triggering an immediate hardware reset.