feat: got rid off runtime panics.

This commit is contained in:
Andrey Parhomenko 2024-01-17 16:39:52 +03:00
parent 07a1f562c8
commit ab1437a15b
4 changed files with 45 additions and 27 deletions

12
bot.go
View file

@ -3,9 +3,6 @@ package tg
import ( import (
"errors" "errors"
"sort" "sort"
//"fmt"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
) )
@ -66,6 +63,15 @@ func (bot *Bot) Send(
return &msg, nil return &msg, nil
} }
func (bot *Bot) Sendf(
sid SessionId, format string, v ...any,
) (*Message, error){
return bot.Send(
sid,
NewMessage(format, v...),
)
}
// Send to the session specified its ID raw chattable from the tgbotapi. // Send to the session specified its ID raw chattable from the tgbotapi.
func (bot *Bot) SendRaw( func (bot *Bot) SendRaw(
sid SessionId, v tgbotapi.Chattable, sid SessionId, v tgbotapi.Chattable,

View file

@ -170,7 +170,10 @@ func (compo *CommandCompo) Serve(c *Context) {
c.WithUpdate(u).Run(cmd.Action) c.WithUpdate(u).Run(cmd.Action)
if cmd.Widget != nil { if cmd.Widget != nil {
cmdUpdates.Close() cmdUpdates.Close()
cmdUpdates = c.WithUpdate(u).RunWidget(cmd.Widget) cmdUpdates, err = c.WithUpdate(u).RunWidget(cmd.Widget)
if err != nil {
continue
}
} }
continue continue
} }

View file

@ -224,21 +224,14 @@ func (c *Context) History() []Path {
} }
// Changes screen of user to the Id one. // Changes screen of user to the Id one.
func (c *Context) Go(pth Path, args ...any) { func (c *Context) Go(pth Path, args ...any) error {
var err error
if pth == "" { if pth == "" {
c.pathHistory = []Path{} c.pathHistory = []Path{}
return return nil
} }
var back bool var back bool
if pth == "-" { if pth == "-" {
ln := len(c.pathHistory)
if ln <= 1 {
pth = "/"
} else {
pth = c.pathHistory[ln-2]
c.pathHistory = c.pathHistory[:ln-1]
back = true
}
} }
// Getting the screen and changing to // Getting the screen and changing to
// then executing its widget. // then executing its widget.
@ -247,7 +240,7 @@ func (c *Context) Go(pth Path, args ...any) {
} }
if !c.PathExist(pth) { if !c.PathExist(pth) {
panic(ScreenNotExistErr) return ScreenNotExistErr
} }
if !back && c.Path() != pth { if !back && c.Path() != pth {
@ -258,10 +251,15 @@ func (c *Context) Go(pth Path, args ...any) {
screen := c.Bot.behaviour.Screens[pth] screen := c.Bot.behaviour.Screens[pth]
c.skippedUpdates.Close() c.skippedUpdates.Close()
if screen.Widget != nil { if screen.Widget != nil {
c.skippedUpdates = c.RunWidget(screen.Widget, args...) c.skippedUpdates, err = c.RunWidget(screen.Widget, args...)
if err != nil {
return err
}
} else { } else {
panic("no widget defined for the screen") return NoWidgetForScreenErr
} }
return nil
} }
func (c *Context) PathExist(pth Path) bool { func (c *Context) PathExist(pth Path) bool {
@ -278,15 +276,15 @@ func (c *Context) makeArg(args []any) any {
return arg return arg
} }
func (c *Context) RunCompo(compo Component, args ...any) *UpdateChan { func (c *Context) RunCompo(compo Component, args ...any) (*UpdateChan, error) {
if compo == nil { if compo == nil {
return nil return nil, nil
} }
s, ok := compo.(Sendable) s, ok := compo.(Sendable)
if ok { if ok {
msg, err := c.Send(s) msg, err := c.Send(s)
if err != nil { if err != nil {
panic("could not send the message") return nil, err
} }
s.SetMessage(msg) s.SetMessage(msg)
} }
@ -300,24 +298,31 @@ func (c *Context) RunCompo(compo Component, args ...any) *UpdateChan {
// the channel is closed and close it by themselves. // the channel is closed and close it by themselves.
updates.Close() updates.Close()
}() }()
return updates return updates, nil
} }
// Run widget in background returning the new input channel for it. // Run widget in background returning the new input channel for it.
func (c *Context) RunWidget(widget Widget, args ...any) *UpdateChan { func (c *Context) RunWidget(widget Widget, args ...any) (*UpdateChan, error) {
var err error
if widget == nil { if widget == nil {
return nil return nil, EmptyWidgetErr
} }
pth := c.Path() pth := c.Path()
compos := widget.Render(c.WithArg(c.makeArg(args))) compos := widget.Render(c.WithArg(c.makeArg(args)))
// Leave if changed path. // Leave if changed path or components are empty.
if compos == nil || pth != c.Path() { if compos == nil || pth != c.Path() {
return nil return nil, EmptyCompoErr
} }
chns := make([]*UpdateChan, len(compos)) chns := make([]*UpdateChan, len(compos))
for i, compo := range compos { for i, compo := range compos {
chns[i] = c.RunCompo(compo, args...) chns[i], err = c.RunCompo(compo, args...)
if err != nil {
for _, chn := range chns {
chn.Close()
}
return nil, err
}
} }
ret := NewUpdateChan() ret := NewUpdateChan()
@ -350,7 +355,7 @@ func (c *Context) RunWidget(widget Widget, args ...any) *UpdateChan {
} }
}() }()
return ret return ret, nil
} }
// Simple way to read strings for widgets. // Simple way to read strings for widgets.

View file

@ -19,6 +19,10 @@ var (
MapCollisionErr = errors.New("map collision occured") MapCollisionErr = errors.New("map collision occured")
ContextNotExistErr = errors.New("the context does not exist") ContextNotExistErr = errors.New("the context does not exist")
StatusCodeErr = errors.New("not success response status code") StatusCodeErr = errors.New("not success response status code")
NotSendErr = errors.New("could not send message")
NoWidgetForScreenErr = errors.New("no widget defined for the screen")
EmptyCompoErr = errors.New("empty component")
EmptyWidgetErr = errors.New("empty widget")
) )
func (wut WrongUpdateType) Error() string { func (wut WrongUpdateType) Error() string {