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 (
"errors"
"sort"
//"fmt"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
@ -66,6 +63,15 @@ func (bot *Bot) Send(
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.
func (bot *Bot) SendRaw(
sid SessionId, v tgbotapi.Chattable,

View file

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

View file

@ -224,21 +224,14 @@ func (c *Context) History() []Path {
}
// 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 == "" {
c.pathHistory = []Path{}
return
return nil
}
var back bool
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
// then executing its widget.
@ -247,7 +240,7 @@ func (c *Context) Go(pth Path, args ...any) {
}
if !c.PathExist(pth) {
panic(ScreenNotExistErr)
return ScreenNotExistErr
}
if !back && c.Path() != pth {
@ -258,10 +251,15 @@ func (c *Context) Go(pth Path, args ...any) {
screen := c.Bot.behaviour.Screens[pth]
c.skippedUpdates.Close()
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 {
panic("no widget defined for the screen")
return NoWidgetForScreenErr
}
return nil
}
func (c *Context) PathExist(pth Path) bool {
@ -278,15 +276,15 @@ func (c *Context) makeArg(args []any) any {
return arg
}
func (c *Context) RunCompo(compo Component, args ...any) *UpdateChan {
func (c *Context) RunCompo(compo Component, args ...any) (*UpdateChan, error) {
if compo == nil {
return nil
return nil, nil
}
s, ok := compo.(Sendable)
if ok {
msg, err := c.Send(s)
if err != nil {
panic("could not send the message")
return nil, err
}
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.
updates.Close()
}()
return updates
return updates, nil
}
// 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 {
return nil
return nil, EmptyWidgetErr
}
pth := c.Path()
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() {
return nil
return nil, EmptyCompoErr
}
chns := make([]*UpdateChan, len(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()
@ -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.

View file

@ -19,6 +19,10 @@ var (
MapCollisionErr = errors.New("map collision occured")
ContextNotExistErr = errors.New("the context does not exist")
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 {