Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 23 additions & 27 deletions internal/lnbits/lnbits.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ import (
"github.com/imroc/req"
)

// parseLNbitsError extracts a meaningful error from an LNbits HTTP response.
func parseLNbitsError(resp *req.Resp) Error {
statusCode := resp.Response().StatusCode
rawBody := resp.String()

var reqErr Error
resp.ToJSON(&reqErr)
reqErr.StatusCode = statusCode
if reqErr.Detail == "" && reqErr.Message == "" {
reqErr.RawBody = rawBody
}
return reqErr
}

// NewClient returns a new lnbits api client. Pass your API key and url here.
func NewClient(key, url string) *Client {
return &Client{
Expand All @@ -31,9 +45,7 @@ func (c *Client) GetUser(userId string) (user User, err error) {
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand All @@ -54,9 +66,7 @@ func (c *Client) CreateUserWithInitialWallet(userName, walletName, adminId strin
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}
err = resp.ToJSON(&wal)
Expand All @@ -75,9 +85,7 @@ func (c *Client) CreateWallet(userId, walletName, adminId string) (wal Wallet, e
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}
err = resp.ToJSON(&wal)
Expand All @@ -98,9 +106,7 @@ func (w Wallet) Invoice(params InvoiceParams, c *Client) (lntx Invoice, err erro
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand All @@ -122,9 +128,7 @@ func (c Client) Info(w Wallet) (wtx Wallet, err error) {
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand All @@ -146,9 +150,7 @@ func (c Client) Payments(w Wallet) (wtx Payments, err error) {
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand All @@ -170,9 +172,7 @@ func (c Client) Payment(w Wallet, payment_hash string) (payment LNbitsPayment, e
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand All @@ -188,9 +188,7 @@ func (c Client) Wallets(w User) (wtx []Wallet, err error) {
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand All @@ -214,9 +212,7 @@ func (w Wallet) Pay(params PaymentParams, c *Client) (wtx Invoice, err error) {
}

if resp.Response().StatusCode >= 300 {
var reqErr Error
resp.ToJSON(&reqErr)
err = reqErr
err = parseLNbitsError(resp)
return
}

Expand Down
19 changes: 17 additions & 2 deletions internal/lnbits/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,26 @@ type TransferParams struct {
}

type Error struct {
Detail string `json:"detail"`
Detail string `json:"detail"`
Message string `json:"message"`
StatusCode int `json:"-"`
RawBody string `json:"-"`
}

func (err Error) Error() string {
return err.Detail
if err.Detail != "" {
return err.Detail
}
if err.Message != "" {
return err.Message
}
if err.RawBody != "" {
return fmt.Sprintf("LNbits HTTP %d: %s", err.StatusCode, err.RawBody)
}
if err.StatusCode != 0 {
return fmt.Sprintf("LNbits HTTP %d: unknown error", err.StatusCode)
}
return "unknown LNbits error"
}

type Wallet struct {
Expand Down
5 changes: 4 additions & 1 deletion internal/telegram/error_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ func (el *ErrorLogger) LogError(err error, context string, userInfo ...interface
return
}

// Filter out annoying/irrelevant error messages
// Filter out empty/ghost errors and irrelevant messages
errorMsg := err.Error()
if errorMsg == "" || errorMsg == `{"message":"","Err":{},"code":0}` {
return // Skip empty/meaningless errors
}
if strings.Contains(errorMsg, "[requirePrivateChatInterceptor]") {
return // Skip logging this specific interceptor error
}
Expand Down
24 changes: 20 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,29 @@ func main() {
func startApiServer(bot *telegram.TipBot) {
// log errors from interceptors
bot.Telegram.OnError = func(err error, ctx tb.Context) {
if err == nil {
return
}

errMsg := err.Error()

// Filter out empty/ghost errors from telebot (code:0, empty message)
if errMsg == "" || errMsg == `{"message":"","Err":{},"code":0}` {
return
}

// Filter out annoying interceptor errors
if err != nil && strings.Contains(err.Error(), "[requirePrivateChatInterceptor]") {
return // Skip logging this specific error
if strings.Contains(errMsg, "[requirePrivateChatInterceptor]") {
return
}

// Log errors to Telegram group
if bot.ErrorLogger != nil {
userInfo := []interface{}{}
if ctx.Sender() != nil {
if ctx != nil && ctx.Sender() != nil {
userInfo = append(userInfo, ctx.Sender())
}
if ctx.Chat() != nil {
if ctx != nil && ctx.Chat() != nil {
userInfo = append(userInfo, ctx.Chat())
}
bot.ErrorLogger.LogError(err, "Telegram Bot Error", userInfo...)
Expand All @@ -72,6 +83,11 @@ func startApiServer(bot *telegram.TipBot) {
// start external api server
s := api.NewServer(internal.Configuration.Bot.LNURLServerUrl.Host)

s.AppendRoute("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}, http.MethodGet)

// append lnurl ctx functions
lnUrl := lnurl.New(bot)
s.AppendRoute("/.well-known/lnurlp/{username}", lnUrl.Handle, http.MethodGet)
Expand Down
Loading