# Error

{% embed url="<https://youtu.be/yY9lL4Jxkd8>" %}
Error
{% endembed %}

## Setup

Target contract:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract Error {
    error NotAuthorized();

    function throwError() external {
        require(false, "not authorized");
    }

    function throwCustomError() external {
        revert NotAuthorized();
    }
}
```

Test file:

```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.18;

import "forge-std/Test.sol";
import {Error} from "../src/Error.sol";

contract ErrorTest is Test {
    Error public err;

    function setUp() public {
        err = new Error();
    }

    function testFail() public {
        err.throwError();
    }

    function testRevert() public {
        vm.expectRevert();
        err.throwError();
    }

    function testRequireMessage() public {
        vm.expectRevert(bytes("not authorized"));
        err.throwError();
    }

    function testCustomError() public {
        vm.expectRevert(Error.NotAuthorized.selector);
        err.throwCustomError();
    }

    // Add label to assertions
    function testErrorLabel() public {
        assertEq(uint256(1), uint256(1), "test 1");
        assertEq(uint256(1), uint256(1), "test 2");
        assertEq(uint256(1), uint256(1), "test 3");
        assertEq(uint256(1), uint256(2), "test 4");
        assertEq(uint256(1), uint256(1), "test 5");
    }
}
```

## vm.expectRevert()

If we want a test case to simply revert, use `testFail` prefix in the function name:

```solidity
    function testFail() public {
        err.throwError();
    }
```

Another way of doing the same thing is to use `test` prefix in the function name and `vm.expectRevert()` before that operation:

```solidity
    function testRevert() public {
        vm.expectRevert();
        err.throwError();
    }
```

## Test require error message

If we want to test for a `require()` statement's error message, such as the following:

```solidity
    function throwError() external {
        require(false, "not authorized");
    }
```

use `vm.expectRevert(bytes(error_message))`:

```solidity
    function testRequireMessage() public {
        vm.expectRevert(bytes("not authorized"));
        err.throwError();
    }
```

## Custom error

If we want to test for custom error instead, such as the following:

```solidity
    function throwCustomError() external {
        revert NotAuthorized();
    }
```

use `vm.expectRevert(Error.custom_error_name.selector)`:

```solidity
    function testCustomError() public {
        vm.expectRevert(Error.NotAuthorized.selector);
        err.throwCustomError();
    }
```

## Label assertions

If we have a lot of assertions in a test case, Foundry won't tell us which ones succeed and which ones fail. For example:

```solidity
    function testErrorLabel() public {
        assertEq(uint256(1), uint256(1));
        assertEq(uint256(1), uint256(1));
        assertEq(uint256(1), uint256(1));
        assertEq(uint256(1), uint256(2));
        assertEq(uint256(1), uint256(1));
    }
```

The 4th assertion clearly would fail but Foundry won't tell us the failed one is the 4th assertion. In order to distinguish assertions, we can label them with different names:

```solidity
    // Add label to assertions
    function testErrorLabel() public {
        assertEq(uint256(1), uint256(1), "test 1");
        assertEq(uint256(1), uint256(1), "test 2");
        assertEq(uint256(1), uint256(1), "test 3");
        assertEq(uint256(1), uint256(2), "test 4");
        assertEq(uint256(1), uint256(1), "test 5");
    }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfnote/web3-security-research/foundry/error.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
