Skip to main content
Version: 0.0.7

Migrating from 0.0.6 to 0.0.7

Overview

Version 0.0.7 contains no breaking changes. All additions are either:

  • Additive — new features, new properties with safe defaults
  • Fail-fast for existing misconfigurations — errors that previously caused silent misbehaviour now throw BeanCreationException at startup so they are caught before production

Upgrade is a single version bump for most projects:

<dependency>
<groupId>uz.osoncode.easygram</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>0.0.7</version>
</dependency>

What might affect your application

1. Duplicate handler methods — startup failure

If your project has two @BotController methods with the same routing condition (same annotation

  • same value + same effective @BotChatState), the application will now fail to start.

How to find them: Look for BeanCreationException in your startup logs with the message Duplicate handler mapping detected. The message names both conflicting methods.

What to do:

  • If the duplication is accidental — remove or rename one method.
  • If you intended two handlers for the same condition with priority — add distinct @BotOrder values (this is valid and no longer triggers the error).
// ✅ Valid — different @BotOrder values, same condition
@BotCommand("/admin")
@BotOrder(1)
public String onAdminSuperUser() { ... }

@BotCommand("/admin")
@BotOrder(100)
public String onAdminFallback() { ... }

2. Webhook requireSecretToken — startup failure on misconfiguration

Only affects you if you set require-secret-token: true in your webhook configuration.

If require-secret-token: true is set but secret-token is absent or blank, the application now fails at startup. Previously this combination was silently accepted.

Fix: Either provide the secret-token property, or remove require-secret-token: true:

easygram:
update:
webhook:
require-secret-token: true
secret-token: ${WEBHOOK_SECRET} # ← must be present and non-blank

3. Blank @BotMarkup / @BotReplyMarkup / @BotForwardChatState — startup failure

If any handler method has a blank string value for these annotations, the application now fails at startup.

Examples that now fail:

@BotMarkup("")                  // ← BeanCreationException
@BotReplyMarkup("") // ← BeanCreationException
@BotForwardChatState("") // ← BeanCreationException

Fix by providing the correct non-blank value (the markup identifier or state name).


4. Error counter — new exception tag (dashboard action needed)

The easygram.update.error_total counter now has an exception dimension containing the simple class name of the exception.

Impact: If you have Grafana dashboards, Prometheus alerting rules, or Datadog monitors querying easygram_update_error_total without a label selector, they continue to work (summing across all exception types).

If you have queries that expect the counter to have no labels, add a wildcard matcher:

# Before (still works — sums all exception types)
rate(easygram_update_error_total[1m])

# Recommended — be explicit about aggregation
sum(rate(easygram_update_error_total[1m])) by (exception)

# Filter to a specific type
rate(easygram_update_error_total{exception="TelegramApiException"}[1m])

5. Telegram send error classification — 4xx suppressed, 5xx propagated

BotApiMethodsSenderFilter now distinguishes between retryable and non-retryable Telegram API errors:

  • 4xx (client errors) — logged as ERROR and suppressed (not re-thrown). These are permanent failures: resending the same message payload will never succeed. Suppressing prevents broker transports (RabbitMQ consumer) from entering an infinite requeue loop. Fix the message content in your handler.
  • 5xx / network errors — logged as ERROR and re-thrown so that your @BotExceptionHandler methods can handle them (retry, alert, etc.).

If your bot has a broad Telegram error handler: Handlers that previously caught all TelegramApiException instances will now only fire for 5xx / network errors. 4xx errors are suppressed before reaching any handler.

// Receives only 5xx and network errors — 4xx are suppressed at the sender filter
@BotExceptionHandler(TelegramApiException.class)
public void onTelegramError(TelegramApiException e) {
log.error("Transient Telegram API error: {}", e.getMessage());
}

6. Duplicate @BotExceptionHandler detection — startup failure

If your project has two methods inside @BotController beans (or two inside @BotControllerAdvice beans) that declare @BotExceptionHandler for the same exception type and the same effective @BotChatState, the application now fails to start.

How to find them: Look for BeanCreationException with Duplicate @BotExceptionHandler mapping detected in your startup logs. The message names both conflicting methods.

What to do:

  • Remove or rename one of the conflicting exception handler methods.
  • If you need different behavior per state — add distinct @BotChatState to each method.
  • A @BotController and a @BotControllerAdvice handler for the same exception type are in separate priority groups and are not flagged as duplicates.

7. RabbitMQ consumer: ACK-always policy

If you use the RABBIT_CONSUMER transport, RabbitBotUpdateListener now always ACKs AMQP messages — regardless of whether processing succeeded or failed. Previously, an exception was re-thrown, causing the AMQP container to NACK and requeue the message indefinitely.

Impact: Failed messages are no longer automatically retried via requeue. If you relied on the requeue behavior for retry logic, configure a Dead-Letter Exchange (DLX) on the broker to route failed messages to a separate queue for inspection and replay.


New features (additive, no migration required)

FeatureHow to use
Body size limitSet easygram.update.webhook.max-body-bytes: <bytes> — default is unlimited
@BotStartTrigger lambdaUse as a lambda in @Bean methods
Regex cache tuningUp to 512 @BotTextPattern regexes are cached — no configuration needed

Full changelog

See What's New in 0.0.7 for the complete feature summary.