История одного «бага» в коде на Go

Пришлось мне работать над одним проектом на Go, т.к. я предполагал делать в него коммиты, утянул проект не через go get, а по-честному:

git clone server/project.git

Написал свой код, в нём выполнялся вызов одной из сущестующих функций проекта, возвращённая функцией ошибка сравнивалась с определённой типовой ошибкой из этого же проекта:

err := project.Function()
switch err {
case nil:
    // all ok
case project.SpecialErr:
    // handle known error
default:
    // handle all other errors
}

И тут я столкнулся с тем, что при возврате функцией значения SpecialErr, мой код обрабатывает его веткой default.

Ломал голову я довольно долго, смущало также то, что вывод:

log.Print(err==project.SpecialErr)

внутри функции Function непосредственно перед возвратом значения project.SpecialErr показывал true, в то время как аналогичная проверка для полученного значения в моём коде давала уверенное false.

Разгадка такого странного поведения крылась в различиях в объявлении импортов:

Внутри других файлов проекта импорты были заданы следующим образом:

import "server/project.git"

В то время как в своём коде я объявил импорт так:

import "server/project"

Несмотря на то, что каталог с проектом назывался $GOPATH/src/server/project (git clone удалил суффикс) и весь код успешно собирался, в реальности в своём коде я сравнивал равенство двух переменных из разных путей импорта: функция возвращала server/project.git/SpecialErr, мой код проверял совпадение с server/project/SpecialErr.

comments powered by Disqus