package camfish import "fmt" import "strings" // Error enumerates common errors in this package. type Error string; const ( ErrNotFound Error = "not found" ErrNotRunning Error = "not running" ErrProcessKilled Error = "process killed" ErrExtraneousValues Error = "extraneous value(s)" ErrSectionHeadingMalformed Error = "section heading malformed" ErrPairMalformed Error = "key/value pair malformed" ErrKeyEmpty Error = "key empty" ) // Error implements the error interface. func (err Error) Error() string { return string(err) } // ConfigError pairs an error with a location in a config file. type ConfigError struct { File string Key string Line int Column int Err error } // Error implements the error interface. func (err ConfigError) Error() string { out := strings.Builder { } if err.File != "" { out.WriteString(err.File) } if err.Key != "" { fmt.Fprintf(&out, "[%s]", err.Key) } switch { case err.Line != 0 && err.Column != 0: if out.Len() > 0 { out.WriteRune(':') } fmt.Fprintf(&out, "%d:%d", err.Line, err.Column) case err.Line != 0: if out.Len() > 0 { out.WriteRune(':') } fmt.Fprintf(&out, "%d", err.Line) } if out.Len() > 0 { out.WriteString(": ") } if err.Err == nil { out.WriteString("configuration error") } else { fmt.Fprint(&out, err.Err) } return out.String() } // Unwrap returns err.Err. func (err ConfigError) Unwrap() error { return err.Err } // NewConfigError creates a new config error with the given key and config. It // will attempt to fill in as many details as possible with the information // given. If the config has a method with an identical name and signature to // this function, it will be called and its value will be returned. Otherwise, // an error is returned containing only the provided information. func NewConfigError(config Config, key string, index int, wrapped error) ConfigError { type configErrorFactory interface { NewConfigError(string, int, error) ConfigError } if config, ok := config.(configErrorFactory); ok { return config.NewConfigError(key, index, wrapped) } return ConfigError { Key: key, Err: wrapped, } } // FlagError pairs a flag with a long flag name. type FlagError struct { Long string Err error } // Error implements the error interface. func (err FlagError) Error() string { output := err.Long if output != "" { output = fmt.Sprintf("--%s: ", output) } if err.Err == nil { output += "argument parsing error" } else { output += err.Unwrap().Error() } return output } // Unwrap returns err.Err func (err FlagError) Unwrap() error { return err.Err }