# Error

This Go program demonstrates how to use errors in Go and introduces a custom error type. It defines two functions, `f1` and `f2`, both of which return an `int` and an `error`.

The `f2` function introduces a custom error type `argError`. The `main` function then calls these functions and handles the errors.

```go
package main

import (
    "errors"
    "fmt"
)

// Function f1 returns the result of arg + 3, or an error if arg is 42
func f1(arg int) (int, error) {
    if arg == 42 {
        return -1, errors.New("can't work with 42")
    }
    return arg + 3, nil
}

// Define a custom error type argError, which includes information about the argument and the problem
type argError struct {
    arg  int
    prob string
}

// Implement the Error method for the argError type
func (e *argError) Error() string {
    return fmt.Sprintf("%d - %s", e.arg, e.prob)
}

// Function f2 returns the result of arg + 3, or a custom argError if arg is 42
func f2(arg int) (int, error) {
    if arg == 42 {
        return -1, &argError{arg, "can't work with it"}
    }
    return arg + 3, nil
}

func main() {
    // Use f1 and handle the error
    for _, i := range []int{7, 42} {
        if r, e := f1(i); e != nil {
            fmt.Println("f1 failed:", e)
        } else {
            fmt.Println("f1 worked:", r)
        }
    }

    // Use f2 and handle the custom error type
    for _, i := range []int{7, 42} {
        if r, e := f2(i); e != nil {
            fmt.Println("f2 failed:", e)
        } else {
            fmt.Println("f2 worked:", r)
        }
    }

    // Demonstrate type assertion to access fields of the custom error type
    _, e := f2(42)
    if ae, ok := e.(*argError); ok {
        fmt.Println("Custom error type:")
        fmt.Println(ae.arg)
        fmt.Println(ae.prob)
    }
}
```

#### Output

```
f1 worked: 10
f1 failed: can't work with 42
f2 worked: 10
f2 failed: 42 - can't work with it
42
can't work with it
```

Explanation:

1. The `f1` function returns either the result of `arg + 3` or an error if `arg` is equal to 42. It uses the standard `errors.New` function to create a simple error.
2. The `argError` type is a custom error type with fields `arg` and `prob`. It has an `Error` method to implement the `error` interface.
3. The `f2` function returns either the result of `arg + 3` or a custom `argError` if `arg` is equal to 42.
4. The `main` function demonstrates the usage of these functions:
   * Calls to `f1` and `f2` are made in loops, and errors are handled using conditional statements.
   * For the custom error type `argError`, type assertion is used to access its fields.

This example illustrates how to work with errors in Go, including creating custom error types and handling errors returned by functions.
