#go #error-handling #package
#Вперед #обработка ошибок #пакет
Вопрос:
У меня есть пакет с определенными экспортированными ошибками и метод, который анализирует строку, которая может содержать данные об ошибках. Есть ли способ вернуть экспортированную ошибку, соответствующую строке? Возможно ли это только с помощью a switch-case
?
package foobarbaz
/* Import */
var (
ErrFoo = errors.New("foo")
ErrBar = errors.New("bar")
/* More... */
)
func ParseStringWithErr(s string) (string, error) {
// Data looks like e.g. "data:foo"
var result string
var err error
result = getResultAsString(s)
err = errors.New(getErrAsString(s)) // Will be "foo", "bar", etc... as string
return result, err // DOESN'T WORK
// New error won't be equivalent to the exported Errors
}
На самом деле это немного сложнее, чем это, поскольку проанализированные значения затем сохраняются в объекте, который затем возвращается. Возможно, что анализируемая строка не содержит данных об ошибке, и в этом случае часть getErrAsString просто не вызывается (и ошибка сохраняет свое нулевое значение <nil>
, которое является правильным).
Очевидно, что я могу написать функцию, которая просто включает строку ошибки, но есть несколько экспортированных ошибок, и кажется странным писать случай для каждой из них.
Ответ №1:
По сути, вы хотите error
получить значение из строки, из ее строки ошибки.
Инициализируйте и используйте для этого простую карту:
var errMap = map[string]error{}
func init() {
for _, err := range []error{ErrFoo, ErrBar} {
errMap[err.Error()] = err
}
}
func LookupError(s string) (err error, ok bool) {
err, ok = errMap[s]
return
}
Тестирование:
err, ok := LookupError("foo")
fmt.Println(err, ok, err == ErrFoo)
err, ok = LookupError("bar")
fmt.Println(err, ok, err == ErrBar)
err, ok = LookupError("baz")
fmt.Println(err, ok)
Какие результаты (попробуйте на Go Playground):
foo true true
bar true true
<nil> false