(new): v1.2 release
Golang lint / lint (push) Successful in 11m32s

This commit is contained in:
2026-08-19 14:58:25 +03:00
parent f03a081ed6
commit 29b208eeec
79 changed files with 7301 additions and 2060 deletions
+123 -50
View File
@@ -50,6 +50,10 @@ func emitContextError(ctx *MessageContext, event ErrorEvent) {
if ctx.Logger != nil {
ctx.Logger.Errorln(event.Err)
}
if ctx.eventEmitter != nil {
ctx.eventEmitter(ctx.Context(), event)
return
}
if ctx.observer == nil {
return
}
@@ -63,94 +67,150 @@ func emitContextError(ctx *MessageContext, event ErrorEvent) {
// UpdateReceivedEvent describes an update entering the bot runtime.
type UpdateReceivedEvent struct {
UpdateID int
// UpdateID identifies the Telegram update.
UpdateID int
// UpdateType identifies the normalized update kind.
UpdateType tgapi.UpdateType
FromID int64
ChatID int64
// FromID identifies the originating user when available.
FromID int64
// ChatID identifies the originating chat when available.
ChatID int64
}
// UpdateHandledEvent describes a completed update execution path.
type UpdateHandledEvent struct {
UpdateID int
// UpdateID identifies the Telegram update.
UpdateID int
// UpdateType identifies the normalized update kind.
UpdateType tgapi.UpdateType
FromID int64
ChatID int64
Duration time.Duration
Handled bool
// FromID identifies the originating user when available.
FromID int64
// ChatID identifies the originating chat when available.
ChatID int64
// Duration is the total framework handling time.
Duration time.Duration
// Handled reports whether a registered path handled the update.
Handled bool
}
// HandlerStartedEvent describes a handler about to execute.
type HandlerStartedEvent struct {
UpdateID int
UpdateType tgapi.UpdateType
Plugin string
// UpdateID identifies the Telegram update.
UpdateID int
// UpdateType identifies the normalized update kind.
UpdateType tgapi.UpdateType
// Plugin names the plugin that owns the handler.
Plugin string
// HandlerKind classifies the handler.
HandlerKind HandlerEventKind
// HandlerName identifies the handler within its plugin and kind.
HandlerName string
FromID int64
ChatID int64
// FromID identifies the originating user when available.
FromID int64
// ChatID identifies the originating chat when available.
ChatID int64
}
// HandlerFinishedEvent describes a handler that has completed.
type HandlerFinishedEvent struct {
UpdateID int
UpdateType tgapi.UpdateType
Plugin string
// UpdateID identifies the Telegram update.
UpdateID int
// UpdateType identifies the normalized update kind.
UpdateType tgapi.UpdateType
// Plugin names the plugin that owns the handler.
Plugin string
// HandlerKind classifies the handler.
HandlerKind HandlerEventKind
// HandlerName identifies the handler within its plugin and kind.
HandlerName string
FromID int64
ChatID int64
Duration time.Duration
Err error
UserFacing bool
// FromID identifies the originating user when available.
FromID int64
// ChatID identifies the originating chat when available.
ChatID int64
// Duration is the handler execution time.
Duration time.Duration
// Err is the error returned or recovered from the handler.
Err error
// UserFacing reports whether Err is safe to show to the user.
UserFacing bool
}
// SceneTransitionEvent describes a scene state transition.
type SceneTransitionEvent struct {
// Plugin names the plugin that owns the scene.
Plugin string
Scene string
From string
To string
// Scene names the transitioning scene.
Scene string
// From is the previous scene step.
From string
// To is the resulting scene step.
To string
// Action identifies the requested state transition.
Action SceneAction
// FromID identifies the session user when available.
FromID int64
// ChatID identifies the session chat when available.
ChatID int64
}
// PolicyCheckedEvent describes the result of a policy evaluation.
type PolicyCheckedEvent struct {
Name string
Plugin string
FromID int64
ChatID int64
Passed bool
Err error
// Name identifies the evaluated policy.
Name string
// Plugin names the plugin that requested the policy check.
Plugin string
// FromID identifies the evaluated user when available.
FromID int64
// ChatID identifies the evaluated chat when available.
ChatID int64
// Passed reports whether the policy accepted the context.
Passed bool
// Err is the policy evaluation error, if any.
Err error
// Internal reports whether evaluation failed internally rather than denying access.
Internal bool
}
// RunnerFinishedEvent describes a completed background runner execution.
type RunnerFinishedEvent struct {
Name string
// Name identifies the runner.
Name string
// Duration is the callback execution time.
Duration time.Duration
Err error
// Err is the callback error or recovered panic.
Err error
}
// PollingRetryEvent describes a polling retry after a failed getUpdates call.
type PollingRetryEvent struct {
// Attempt is the one-based retry number.
Attempt int
Delay time.Duration
Err error
// Delay is the time before the next polling attempt.
Delay time.Duration
// Err is the polling error that triggered the retry.
Err error
}
// ErrorEvent describes an error routed through framework error handling.
type ErrorEvent struct {
UpdateID int
UpdateType tgapi.UpdateType
Plugin string
// UpdateID identifies the Telegram update when available.
UpdateID int
// UpdateType identifies the normalized update kind when available.
UpdateType tgapi.UpdateType
// Plugin names the component that reported the error.
Plugin string
// HandlerKind classifies the failing handler or runtime component.
HandlerKind HandlerEventKind
// HandlerName identifies the failing handler within its kind.
HandlerName string
FromID int64
ChatID int64
Err error
UserFacing bool
// FromID identifies the originating user when available.
FromID int64
// ChatID identifies the originating chat when available.
ChatID int64
// Err is the reported error.
Err error
// UserFacing reports whether Err is safe to show to the user.
UserFacing bool
}
func (UpdateReceivedEvent) isEvent() {}
@@ -164,6 +224,11 @@ func (PollingRetryEvent) isEvent() {}
func (ErrorEvent) isEvent() {}
// Observer receives best-effort runtime instrumentation events.
//
// During RunWithContext and RunWebhookWithContext, callbacks execute on a
// dedicated dispatcher goroutine in enqueue order and never block update
// handlers. The queue is bounded; overload drops events and emits sampled
// warnings. Runtime shutdown drains events that were already queued.
type Observer interface {
OnUpdateReceived(ctx context.Context, event UpdateReceivedEvent)
OnUpdateHandled(ctx context.Context, event UpdateHandledEvent)
@@ -180,6 +245,10 @@ func (bot *Bot[T]) safeEmitEvent(ctx context.Context, event Event) {
if bot.observer == nil {
return
}
if bot.observerAsync != nil {
bot.observerAsync.enqueue(ctx, event)
return
}
defer func() {
if r := recover(); r != nil {
if bot.logger != nil {
@@ -191,24 +260,28 @@ func (bot *Bot[T]) safeEmitEvent(ctx context.Context, event Event) {
}
func (bot *Bot[T]) emitEvent(ctx context.Context, event Event) {
emitObserverEvent(bot.observer, ctx, event)
}
func emitObserverEvent(observer Observer, ctx context.Context, event Event) {
switch e := event.(type) {
case UpdateReceivedEvent:
bot.observer.OnUpdateReceived(ctx, e)
observer.OnUpdateReceived(ctx, e)
case UpdateHandledEvent:
bot.observer.OnUpdateHandled(ctx, e)
observer.OnUpdateHandled(ctx, e)
case HandlerStartedEvent:
bot.observer.OnHandlerStarted(ctx, e)
observer.OnHandlerStarted(ctx, e)
case HandlerFinishedEvent:
bot.observer.OnHandlerFinished(ctx, e)
observer.OnHandlerFinished(ctx, e)
case SceneTransitionEvent:
bot.observer.OnSceneTransition(ctx, e)
observer.OnSceneTransition(ctx, e)
case PolicyCheckedEvent:
bot.observer.OnPolicyChecked(ctx, e)
observer.OnPolicyChecked(ctx, e)
case RunnerFinishedEvent:
bot.observer.OnRunnerFinished(ctx, e)
observer.OnRunnerFinished(ctx, e)
case PollingRetryEvent:
bot.observer.OnPollingRetry(ctx, e)
observer.OnPollingRetry(ctx, e)
case ErrorEvent:
bot.observer.OnError(ctx, e)
observer.OnError(ctx, e)
}
}