Skip to content

connector: map errors to message statuses, resperrors and bridge states - #274

Merged
Fizzadar merged 4 commits into
mainfrom
indent/error-mapping
Oct 22, 2026
Merged

Fizzadar merged 4 commits into
mainfrom
indent/error-mapping

Conversation

@Fizzadar

Copy link
Copy Markdown
Contributor

LINE failures mostly reached users as raw Go errors: most Matrix handlers returned bare LINE/HTTP errors (shown as generic retriable failures), group creation and several QR login steps failed as bare 500s, a login RespError used HTTP 429 (which clients retry automatically), and two bridge states put raw error text in Message. The SSE loop also never reported a dropped stream, so the login stayed CONNECTED through LINE outages and network loss.

Library errors

  • Unexpected HTTP statuses from Talk RPCs, OBS uploads/downloads, the SSE stream and page info now return *line.HTTPError{StatusCode}, with line.HTTPStatusCode(err) to read it, so callers can tell rate limits, server errors and rejections apart. Error strings are unchanged, so the existing string-based auth/TalkException classifiers keep working.
  • The OBS upload and page info requests are built with the client's request context (http.NewRequestWithContext(c.requestContext(), ...)), like the Talk RPCs already were.
  • New line.IsTalkException(err) for "LINE rejected this call" responses.

Sends (message statuses)

  • New wrapSendError used by HandleMatrixMessage, HandleMatrixMessageRemove, HandleMatrixReaction, HandleMatrixReactionRemove, HandleMatrixLeaveRoom, HandleMatrixAcceptMessageRequest, HandleMatrixDeleteChat and HandleMatrixBlockUser. Errors that already carry a MessageStatus pass through unchanged. Otherwise:
    • session invalidated / client superseded / auth error after recovery failed → certain, "not logged in to LINE, reconnect and try again"
    • not a member of the chat → NoPermission, FAIL, certain
    • context timeout/cancel → left uncertain
    • HTTP 429 → NetworkError, certain
    • HTTP 5xx → NetworkError, left uncertain
    • other TalkException / 4xx rejections → NetworkError, certain
    • anything else (transport errors) → "failed to reach LINE", left uncertain
  • Sending to a blocked contact is now NoPermission + FAIL with a human message instead of the raw error text as a generic retriable failure.
  • Matrix media download failures wrap bridgev2.ErrMediaDownloadFailed, HEIC conversion failures ErrMediaConvertFailed, and unsupported msgtypes ErrUnsupportedMessageType.
  • E2EE OBS uploads (done before the message is sent) map HTTP 413 to ErrMediaTooLarge, auth failures through wrapSendError, and everything else to ErrMediaReuploadFailed (certain).
  • Encryption/payload-building failures go through a separate wrapConvertError that marks them certain.
  • Group key fetch failures that aren't the existing "reconnect required" or plaintext-fallback cases now go through wrapSendError.
  • Plain media is uploaded after sendMessage succeeds. If that upload fails, the status is now FAIL, uncertain, "the message was sent to LINE, but the attachment failed to upload", rather than a retriable error that would post the message again.
  • Unsend: "message too old" now has a human message and keeps the LINE error in the chain; "not found" is Unsupported + FAIL.

Login and provisioning (RespErrors)

  • QR login failures from StartQRLogin, VerifyQRCertificate, CreatePinCode and QRCodeLoginV2, and the post-login profile check in finishLogin ("failed to verify token"), now go through the existing wrapLineLoginError instead of reaching clients as bare 500s.
  • ErrLoginTooManyAttempts now uses status 400 instead of 429, so clients don't silently retry the login. ErrLoginUnknown is built from mautrix.MUnknown.
  • New wrapLineRespError for CreateGroup. It returns fmt.Errorf("%w: %w", mapped, err):
    • auth / session invalidated → M_FORBIDDEN
    • not a member → M_FORBIDDEN; TalkException "not found" → M_NOT_FOUND
    • HTTP 429 → M_LIMIT_EXCEEDED with status 400
    • other TalkException / 4xx → M_FORBIDDEN "LINE rejected the request"
    • anything else → 500 M_UNKNOWN

Bridge states

  • line-login-failed and line-token-expired no longer put the raw error in Message; it moved to Info["go_error"], and human messages are registered in status.BridgeStateHumanErrors. RELOGIN stays explicit because the pinned mautrix-go predates the framework default.
  • When the SSE stream drops with a non-auth error (not EOF or the idle-timeout probe path), the connector sends TRANSIENT_DISCONNECT line-sse-disconnected once, and CONNECTED again on the first event after the stream comes back. The existing reconnect loop is unchanged.

Not changed: a pre-upload media size check (LINE's limit isn't known from the code). This doesn't conflict with #271; a trial merge of its head is clean.

bridgelint is clean (bridgelint -verbose ./... exits 0 with no findings; before: 19 errors, 16 warnings, 1 info). go build ./..., go vet and staticcheck (excluding generated pkg/ltsm) are clean, and the existing pkg/connector and pkg/line tests pass. One existing test was updated because the reaction-specific not-a-member helper was folded into the shared mapper.

View in Indent
Tag @indent to continue the conversation here.

@indent
indent Bot marked this pull request as ready for review October 22, 2026 12:27
@indent

indent Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Issues

All clear! No issues remaining. 🎉

2 issues already resolved
  • After an SSE drop, the bridge state only returns to CONNECTED when a real operation arrives, because pings are filtered out before the handler. Quiet accounts stay in TRANSIENT_DISCONNECT even though the stream has reconnected. (fixed by commit b7518ad)
    Found by Indent Review Agent
  • SSE drop/reconnect sends TRANSIENT_DISCONNECT then CONNECTED even when the line-e2ee-key-missing BAD_CREDENTIALS state is active. This hides the relogin prompt while decryption is still broken. (fixed by commit 32431ac)
    Found by Indent Review Agent

CI Checks

All CI checks passed on 32431ac.

Review agents

Select any unchecked box below to run or rerun that agent.

Passed (1)
  • Indent Review Agent · Both earlier findings fixed; nothing new found
Full results

Indent Review Agent

  • Summary: Both earlier findings fixed; nothing new found
  • Last ran on commit: 32431ac0
  • Latest result
    {
      "summary": "Both earlier findings fixed; nothing new found",
      "findings": []
    }

Comment thread pkg/connector/sync.go Outdated
Comment thread pkg/connector/client.go
@Fizzadar
Fizzadar merged commit 72c7a51 into main Oct 22, 2026
9 checks passed
@Fizzadar
Fizzadar deleted the indent/error-mapping branch October 22, 2026 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant