(new): rich message support
(fix): runtime reliability (tests): regression coverage (doc): v1.1 release notes
This commit is contained in:
+31
-1
@@ -2,6 +2,7 @@ package laniakea
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.scuroneko.dev/scuroneko/extypes"
|
||||
"git.scuroneko.dev/scuroneko/laniakea/tgapi"
|
||||
@@ -292,6 +293,9 @@ func (p *Plugin[T]) executeMiddlewares(ctx *MessageContext, db T) bool {
|
||||
// If async, return value is ignored.
|
||||
type MiddlewareExecutor[T AppData] func(ctx *MessageContext, db T) bool
|
||||
|
||||
// ErrMiddlewareExecutorNil reports an attempt to execute middleware without a callback.
|
||||
var ErrMiddlewareExecutorNil = errors.New("middleware executor is nil")
|
||||
|
||||
// Middleware represents a reusable execution interceptor.
|
||||
// Can be synchronous (blocking) or asynchronous (non-blocking).
|
||||
type Middleware[T AppData] struct {
|
||||
@@ -306,7 +310,7 @@ func NewMiddleware[T AppData](name string, executor MiddlewareExecutor[T]) Middl
|
||||
return Middleware[T]{name, executor, 0, false}
|
||||
}
|
||||
|
||||
// SetOrder sets the execution order (currently ignored).
|
||||
// SetOrder sets the bot-level middleware execution order.
|
||||
func (m Middleware[T]) SetOrder(order int) Middleware[T] {
|
||||
m.order = order
|
||||
return m
|
||||
@@ -330,12 +334,38 @@ func (m Middleware[T]) SetAsync(async bool) Middleware[T] {
|
||||
// must treat those fields as read-only — mutating them races the sync chain
|
||||
// that mutates the same context concurrently.
|
||||
func (m Middleware[T]) Execute(ctx *MessageContext, db T) bool {
|
||||
if m.executor == nil {
|
||||
reportMiddlewareError(ctx, m.name, ErrMiddlewareExecutorNil)
|
||||
return false
|
||||
}
|
||||
if m.async {
|
||||
ctxCopy := *ctx
|
||||
go func(ctx MessageContext) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
reportMiddlewareError(&ctx, m.name, fmt.Errorf("middleware %q panicked: %v", m.name, recovered))
|
||||
}
|
||||
}()
|
||||
m.executor(&ctx, db)
|
||||
}(ctxCopy)
|
||||
return true
|
||||
}
|
||||
return m.executor(ctx, db)
|
||||
}
|
||||
|
||||
func reportMiddlewareError(ctx *MessageContext, name string, err error) {
|
||||
event := ErrorEvent{
|
||||
Plugin: "bot",
|
||||
HandlerKind: HandlerMiddlewareKind,
|
||||
HandlerName: name,
|
||||
Err: err,
|
||||
UserFacing: false,
|
||||
}
|
||||
if ctx != nil {
|
||||
event.UpdateID = ctx.Update.UpdateID
|
||||
event.UpdateType = ctx.Update.Type
|
||||
event.FromID = ctx.FromID
|
||||
event.ChatID = ctx.ChatID
|
||||
}
|
||||
emitContextError(ctx, event)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user