92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"io/fs"
|
|
"log"
|
|
)
|
|
|
|
func main() {
|
|
log.SetFlags(0) // no time stamp
|
|
|
|
// Read a single file
|
|
log.SetPrefix("Reading a single file: ")
|
|
|
|
_, err := ReadFile("no/file")
|
|
if err != nil {
|
|
log.Println("err = ", err)
|
|
}
|
|
|
|
// Unwrap the error returned by os.Open()
|
|
log.Println("errors.Unwrap(err) = ", errors.Unwrap(err))
|
|
|
|
// Confirm that the error is, or wraps, an fs.ErrNotExist error
|
|
log.Println("err is fs.ErrNotExist:", errors.Is(err, fs.ErrNotExist))
|
|
|
|
// Confirm that the error is, or wraps, an fs.PathError.
|
|
// errors.As() assigns the unwrapped PathError to target.
|
|
// This allows reading PathError's Path field.
|
|
target := &fs.PathError{}
|
|
if errors.As(err, &target) {
|
|
log.Printf("err as PathError: path is '%s'\n", target.Path)
|
|
log.Printf("err as PathError: op is '%s'\n", target.Op)
|
|
}
|
|
|
|
// Read files concurrently - handling context errors
|
|
log.SetPrefix("Reading files concurrently: ")
|
|
|
|
_, err = ReadFilesConcurrently([]string{"no/file/a", "no/file/b", "no/file/c"})
|
|
log.Println("err = ", err)
|
|
|
|
// Read multiple files
|
|
log.SetPrefix("Reading multiple files: ")
|
|
|
|
// Passing an empty slice triggers a plain error
|
|
_, err = ReadFiles([]string{})
|
|
log.Println("err = ", err)
|
|
|
|
// Passing multiple paths of non-existing files triggers a joined error
|
|
_, err = ReadFiles([]string{"no/file/a", "no/file/b", "no/file/c"})
|
|
log.Println("joined errors = ", err)
|
|
|
|
// Unwrap the errors inside the joined error
|
|
// A joined error does not have the method "func Unwrap() error"
|
|
// because it does not wrap a single error but rather a slice of errors.
|
|
// Therefore, errors.Unwrap() cannot unwrap the errors and returns nil.
|
|
log.Println("errors.Unwrap(err) = ", errors.Unwrap(err))
|
|
|
|
// To unwrap a joined error, you can type-assert that err has
|
|
// an Unwrap() method that returns a slice of errors.
|
|
e, ok := err.(interface{ Unwrap() []error })
|
|
if ok {
|
|
log.Println("e.Unwrap() = ", e.Unwrap())
|
|
}
|
|
|
|
// Network errors
|
|
log.SetPrefix("Network errors: ")
|
|
|
|
err = connectToTCPServer()
|
|
log.Println("err = ", err)
|
|
|
|
// Recover from a panic
|
|
log.SetPrefix("Recovering from a panic: ")
|
|
|
|
// This example is at the end of main, because the panic
|
|
// causes main to exit. Only the deferred function is
|
|
// called before exiting.
|
|
|
|
defer func() {
|
|
// Is this func invoked from a panic?
|
|
if r := recover(); r != nil {
|
|
// Yes: recover from the panic
|
|
log.Printf("isValidPath panicked: error is '%v'\n", r)
|
|
// ...
|
|
}
|
|
}()
|
|
|
|
// isValidPath panics because of an invalid regexp.
|
|
if isValidPath("/path/to/file") {
|
|
_, _ = ReadFile("/path/to/file")
|
|
}
|
|
}
|