package main

import (
	"errors"
	"fmt"
)

// FooError records an error and what caused it
type FooError struct {
	Op       string
	FooThing string
	Err      error
}

// ErrorCreator creates an error, which is an interface, so we can return *FooError as error

//	   type error interface {
//		       Error() string
//	    }
func ErrorCreator() error {
	return &FooError{
		Op:       "was eating miso soup",
		FooThing: "just happend",
		Err:      errors.New("bad fortune cookie"),
	}

}

func (e *FooError) Error() string { return e.Op + " " + e.FooThing + ": " + e.Err.Error() }

func (e *FooError) Unwrap() error { return e.Err }

func (e *FooError) Thing() string { return e.FooThing }

// The key here is to use "errors.As" to check if the error is of type FooError
func main() {
	if err := ErrorCreator(); err != nil {
		var fooError *FooError
		if errors.As(err, &fooError) {
			fmt.Println("Explain failure thing...:", fooError.Thing())
		} else {
			fmt.Println(err)
		}
	}

}