Вероятно, ошибка в базе данных при попытке проверить функциональность в микросервисе с использованием набора go - PullRequest
1 голос
/ 29 февраля 2020

Я новый ученик микро-услуг в go. Я пытался написать свой собственный микро сервис. Функциональность проста. Запрос на localhost:81/balance/{phone_number} должен вернуть баланс пользователя в базе данных. Всякий раз, когда я отправляю этот запрос, я вижу ошибку:

    net/http.(*conn).serve.func1(0xc00021a000)
        /usr/local/go/src/net/http/server.go:1767 +0x139
panic(0x8fe8e0, 0xccafc0)
        /usr/local/go/src/runtime/panic.go:679 +0x1b2
github.com/jinzhu/gorm.(*DB).clone(0x0, 0x30)
        /home/bita/go/src/github.com/jinzhu/gorm/main.go:848 +0x26
github.com/jinzhu/gorm.(*DB).Where(0x0, 0x8d6720, 0xa04b40, 0xc0001fe060, 0x1, 0x1, 0xc00019e5d0)
        /home/bita/go/src/github.com/jinzhu/gorm/main.go:235 +0x2f
arvan/wallet/Reository.(*repository).GetBalance(0xc000184c40, 0xa180c0, 0xc0001fa2d0, 0xc00022000d, 0x7, 0xa0f020, 0xc0001fa300, 0x0)
        /home/bita/go/src/arvan/wallet/Reository/repo.go:35 +0xeb
arvan/wallet/pkg/service.service.GetBalance(0xa12f80, 0xc000184c40, 0xa0f020, 0xc00019e5d0, 0xa180c0, 0xc0001fa2d0, 0xc00022000d, 0x7, 0xc0001fa270, 0xc0001d0730, ...)
        /home/bita/go/src/arvan/wallet/pkg/service/service.go:31 +0x116
arvan/wallet/pkg/http.makeGetBalanceEndpoint.func1(0xa180c0, 0xc0001fa2d0, 0x90d160, 0xc0001fe040, 0xc0001fe040, 0x0, 0x0, 0x0)
        /home/bita/go/src/arvan/wallet/pkg/http/endpoint.go:25 +0x72
github.com/go-kit/kit/transport/http.Server.ServeHTTP(0xc000184c80, 0x994260, 0x994270, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9946a8, ...)
        /home/bita/go/src/github.com/go-kit/kit/transport/http/server.go:121 +0x1b2
arvan/wallet/pkg/http.commonMiddleware.func1(0xa17240, 0xc00022e000, 0xc000212300)
        /home/bita/go/src/arvan/wallet/pkg/http/server.go:33 +0x100
net/http.HandlerFunc.ServeHTTP(0xc000200020, 0xa17240, 0xc00022e000, 0xc000212300)
        /usr/local/go/src/net/http/server.go:2007 +0x44
github.com/gorilla/mux.(*Router).ServeHTTP(0xc0000d8540, 0xa17240, 0xc00022e000, 0xc000212100)
        /home/bita/go/src/github.com/gorilla/mux/mux.go:210 +0xe2
net/http.serverHandler.ServeHTTP(0xc0001e6000, 0xa17240, 0xc00022e000, 0xc000212100)
        /usr/local/go/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc00021a000, 0xa18000, 0xc0001fc100)
        /usr/local/go/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
        /usr/local/go/src/net/http/server.go:2928 +0x384
level=error service=account time:=2020-02-29T04:38:08.908274665Z caller=main.go:74 exit=interrupt

, которую я предполагаю, когда пытаюсь выполнить запрос в базе данных, это происходит. Я использую sqlite в качестве базы данных и использую gorm для ORM. Я думаю, проблема в этой строке:

    func (repo *repository) GetBalance(ctx context.Context, phoneNumber string) (int, error) {
    var user Entity.UserEntity

    if phoneNumber == "" {
        return -1, RepoErr
    }

    if err := repo.db.Where("phone_number = ?", phoneNumber).Find(&user).Error; err != nil {
        fmt.Println("error: ", err.Error())
        return -1, err
    }

    return user.Balance, nil
}

Я понятия не имею, почему это произошло. Потому что, когда я попробовал с монолитной архитектурой, все работало нормально. Ссылка на весь код: здесь

Это то, что имеет отношение к контексту ???? Ps. Весь мой код был вдохновлен gokit-tutorial и его обучающим видео на youtube.

1 Ответ

0 голосов
/ 29 февраля 2020

Фактическое сообщение об ошибке, которое вы пропустили, находится непосредственно перед трассировкой стека c:

http: panic serving [::1]:53017: runtime error: invalid memory address or nil pointer dereference

Это подсказка, что какой-то указатель не был установлен и равен nil.

При копании глубже я обнаружил, что repo.db не устанавливается (== nil), когда запрос достигает вашего GetBalance метода, поэтому он паникует на repo.db.Where.

Вы пытаетесь установить это поле в файле main.go, куда вы также загружаете базу данных:

var db *gorm.DB
{
    dbDriver := "sqlite3"
    dbName := "demo.db"

    db, err := gorm.Open(dbDriver, dbName)
    if err != nil {
        _ = level.Error(logger).Log("exit", err)
        os.Exit(-1)
    }

    db.AutoMigrate(&Entity.UserEntity{})
}

Этот фрагмент кода содержит небольшую ошибку, связанную с переменное затенение . По сути, ваша переменная db, объявленная выше, отличается от переменной, объявленной в скобках {}, а переменная в скобках - это отдельная база данных. Вы можете решить эту проблему, переименовав его или не объявив его снова (используя :=):

var db *gorm.DB
{
    dbDriver := "sqlite3"
    dbName := "demo.db"

    dbLoaded, err := gorm.Open(dbDriver, dbName) // Rename the variable
    if err != nil {
        _ = level.Error(logger).Log("exit", err)
        os.Exit(-1)
    }

    dbLoaded.AutoMigrate(&Entity.UserEntity{})

    db = dbLoaded // Set `db` of the outer scope to `dbLoaded` of this scope
} // dbLoaded is lost here, but it can be accessed using `db`

Теперь он корректно загружает базу данных (db больше не nil) и доступ в вашем другой модуль теперь также работает правильно.

...