> For the complete documentation index, see [llms.txt](https://cll-devrel.gitbook.io/ccip-bootcamp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cll-devrel.gitbook.io/ccip-bootcamp/day-1/exercise-1-programmable-token-transfers-using-the-defensive-example-pattern/defensive-example-pattern.md).

# Defensive Example Pattern

Another best practice that we will implement is so called Defensive Example, the pattern which allows us to reprocess failed messages without forcing the original transaction to fail. Let's explain how it works.

**Receiving and processing messages**

Upon receiving a message on the destination blockchain, the `ccipReceive` function is called by the CCIP Router. This function serves as the entry point to the contract for processing incoming CCIP messages, enforcing crucial security checks through the `onlyRouter`, and `onlyAllowlisted` modifiers.

Here's the step-by-step breakdown of the process:

1. Entrance through `ccipReceive`:
   * The `ccipReceive` function is invoked with an `Any2EVMMessage` struct containing the message to be processed.
   * Security checks ensure the call is from the authorized router, an allowlisted source chain, and an allowlisted sender.
2. Processing Message:
   * `ccipReceive` calls the `processMessage` function, which is external to leverage Solidity's try/catch error handling mechanism. **Note**: The `onlySelf` modifier ensures that only the contract can call this function.
   * Inside `processMessage`, a check is performed for a simulated revert condition using the `s_simRevert` state variable. This simulation is toggled by the `setSimRevert` function, callable only by the contract owner.
   * If `s_simRevert` is false, `processMessage` calls the `_ccipReceive` function for further message processing.
3. Message Processing in `_ccipReceive`:
   * `_ccipReceive` extracts and stores various information from the message, such as the `messageId`, decoded `sender` address, token amounts, and data.
   * It then emits a `MessageReceived` event, signaling the successful processing of the message.
4. Error Handling:
   * If an error occurs during the processing (or a simulated revert is triggered), the catch block within `ccipReceive` is executed.
   * The `messageId` of the failed message is added to `s_failedMessages`, and the message content is stored in `s_messageContents`.
   * A `MessageFailed` event is emitted, which allows for later identification and reprocessing of failed messages.

**Reprocessing of failed messages**

The `retryFailedMessage` function provides a mechanism to recover assets if a CCIP message processing fails. It's specifically designed to handle scenarios where message data issues prevent entire processing yet allow for token recovery:

1. Initiation:
   * Only the contract owner can call this function, providing the `messageId` of the failed message and the `tokenReceiver` address for token recovery.
2. Validation:
   * It checks if the message has failed using `s_failedMessages.get(messageId)`. If not, it reverts the transaction.
3. Status Update:
   * The error code for the message is updated to `RESOLVED` to prevent reentry and multiple retries.
4. Token Recovery:
   * Retrieves the failed message content using `s_messageContents[messageId]`.
   * Transfers the locked tokens associated with the failed message to the specified `tokenReceiver` as an escape hatch without processing the entire message again.
5. **Event Emission**:
   * An event `MessageRecovered` is emitted to signal the successful recovery of the tokens.

This function showcases a graceful asset recovery solution, protecting user values even when message processing encounters issues.
