Skip to content

Release: develop -> main - #67

Merged
Danswar merged 1 commit into
mainfrom
develop
Jul 29, 2026
Merged

Release: develop -> main#67
Danswar merged 1 commit into
mainfrom
develop

Conversation

@github-actions

Copy link
Copy Markdown

Automatic Release PR

This PR was automatically created after changes were pushed to develop.

Commits: 1 new commit(s)

Checklist

  • Review all changes
  • Verify CI passes
  • Approve and merge when ready for production

* Fall back to text-only posts and collapse Telegram polling noise

TELEGRAM_IMAGES_DIR is unset in the deployed environment, so every
video-bearing notification builds the literal path "undefined/<file>.mp4".
node-telegram-bot-api reinterprets a path that is not a readable file as a
URL, Telegram answers "400 Bad Request: wrong HTTP URL specified", and
sendMessage's catch only logs a warning — the notification is dropped.
Trade, MintingUpdate, SavingUpdate, StablecoinBridgeUpdate and
FrontendCodeRegistered have therefore never reached subscribers, while
text-only alerts kept working and made the bot look healthy. Setting the
env var alone would not help: the media files are not in the image.

Port the guard d-EURO#115 already uses: resolveMediaPath checks the
file with existsSync and returns undefined, so sendMessage degrades to
sendMessage instead of sendVideo.

Separately, attach a 'polling_error' listener. Without one the library
writes its own unformatted console error for every failed poll, and it
retries on a fixed interval with no backoff — a nine-second Telegram
gateway outage produced 27 error lines, and sustained retries earn a 429
on top of the original 502. The listener reports one line per distinct
failure plus one on recovery with duration and attempt count, which turns
the same outage into two lines while still surfacing an escalation from
502 to 429. Both lines are logged at warn so an outage never appears to
stay open under a warn-level log configuration.

No unit tests added: the repo's jest config has rootDir="src" but the
sources live at the repo root, so `yarn test` finds zero tests today.

* Keep missing assets and unrecovered outages visible in the logs

Review follow-up on the first two commits.

The missing-asset notice was logged at debug, which the deployed logger
never emits. Since the assets are absent from the image the fallback is
the permanent state, so the condition would have become completely
silent — it was visible as a warning before this branch. Report it at
warn, once per distinct asset per boot.

The polling signature used the raw error message compared against the
previous one only, which fails in the two cases that actually occur:
"Too Many Requests: retry after N" counts down and a connect failure
carries a rotating gateway address, so each retry looked like a new
failure, and alternating errors re-reported on every poll. Mask digits
out of the signature and track the signatures already reported within
the current outage.

A permanently failing poll — a revoked token answers 401 forever —
reported once and then stayed silent, because the recovery timer only
fires once errors stop. Repeat the report every five minutes while the
outage is open.

Also apply the same media guard to TwitterService, which is the other
caller of the shared helper and logged an upload error per post, move
the outage shape into telegram.types.ts next to the other state types,
and truncate the error text, which wraps the upstream response body.

* Bound the outage signature set and stop over-claiming recovery

Second review follow-up.

The signature prefixed the error code onto a message that the library
already prefixes with that same code, so the prefix discriminated
nothing. Use the message alone.

The signature set had no upper bound: a message carrying a per-attempt
token that survives digit masking - a request id in an upstream error
body reaches the parse-error branch verbatim - produced a fresh
signature per poll, which defeated the collapsing and grew the set
without limit. Cap it, past which only the periodic report remains. A
replay of 2000 such polls now yields 22 lines and 20 retained
signatures instead of 2000 of each.

An error arriving more than the grace period after the previous one
opened and closed its own outage, so an isolated blip cost two lines
where it used to cost one. Skip the closing line for a single attempt.

The closing line said "recovered", but nothing probes the poll - the
grace period only establishes that no further error arrived, and a
request that never settles would look the same. Say what is actually
known instead.
@Danswar
Danswar merged commit 0c5dc88 into main Jul 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant