Wang1rrr opened a new issue, #4870:
URL: https://github.com/apache/rocketmq-dashboard/issues/4870

   ### Before Creating the Bug Report
   
   - [x] I have searched the [open 
issues](https://github.com/apache/rocketmq-dashboard/issues) of this repository 
and believe that this is not a duplicate.
   - [x] This is a defect in RocketMQ Studio, not a usage question and not a 
defect in another Apache RocketMQ repository.
   - [x] I can reproduce this on the current `rocketmq-studio` branch (the 
Studio trunk the pull request template points at), commit 
`4c697f07acde460e2344375cb1f82669f5b270fd`.
   
   ### Studio Version
   
   ```
   branch: rocketmq-studio
   git commit id: 4c697f07acde460e2344375cb1f82669f5b270fd
   deployed as: built from source
   ```
   
   ### Runtime Environment
   
   ```
   OS: Windows 11 (development box); the defect is in the web layer, so the 
host does not matter
   MySQL: required only to run the console against a real cluster; reproduced 
from the sources and the web unit tests
   browser (for UI issues): any; the affected page is 
web/src/pages/instance/message.tsx (消息查询 -> 详情)
   ```
   
   ### Connected RocketMQ Cluster
   
   ```
   RocketMQ version: 5.5.0 self-managed (the Apache provider path); the Aliyun 
and Tencent providers set the same fields
   access mode: Direct / Proxy Local / Proxy Cluster - the response shape is 
identical
   deployment: any cluster holding a message whose body is larger than 64 KiB, 
or whose body is not valid UTF-8
   ```
   
   ### Build Toolchain
   
   ```
   node: v22 (web/ package.json engines), npm ci from web/package-lock.json
   ```
   
   ### Describe the Bug
   
   The server already tells the console when the body it is returning is not 
the whole body, and the console throws that information away.
   
   `RocketMQMessageProvider.displayBody` 
(`provider/apache/RocketMQMessageProvider.java:881`-`:903`) caps what it puts 
on the wire:
   
   - a body that decodes as UTF-8 is cut at `MAX_BODY_DISPLAY_BYTES = 64 * 
1024` (`:87`), returned with `bodyEncoding = "UTF-8"` and `bodyTruncated = 
body.length > textLength`;
   - a body that does not decode is base64-encoded, cut at 
`MAX_BINARY_BODY_DISPLAY_BYTES = 48 * 1024` (`:88`), and returned with 
`bodyEncoding = "BASE64"` and the same truncation flag.
   
   `toRecordVO` (`:867`-`:869`) copies both onto `MessageRecordVO` 
(`instance/message/MessageRecordVO.java:39`-`:40`), the Aliyun provider sets 
them too (`provider/alibaba/AliyunConverters.java:241`, `:243`), and the AI 
tool schema publishes them (`resources/tool-catalog/tools/message.yaml:86`, 
`:88`).
   
   The project's own API specification documents them. `docs/api-spec.md` §8.1 
has a `#### MessageRecord` field table (`:1324`-`:1343`) listing `bodyEncoding` 
(`:1336`, 消息体编码,如 `UTF-8` / `BASE64`), `bodyTruncated` (`:1337`, 消息体是否被截断) and 
`propertiesTruncated` (`:1342`). So this is not an undocumented server 
behaviour that the frontend never learned about - the contract is written down, 
and the frontend type does not implement it.
   
   The web type does not declare them. `web/src/api/message.ts:4`-`:19` lists 
`msgId`, `topic`, `tag`, `key`, `brokerName`, `queueId`, `queueOffset`, `body`, 
`storeTime`, `bornHost`, `storeHost`, `reconsumeTimes`, `properties`, `size` - 
no `bodyEncoding`, no `bodyTruncated`, no `propertiesTruncated`. So no page can 
read them, and `tsc` cannot complain about the omission because the fields are 
simply absent from the contract as far as the frontend knows.
   
   The detail panel then presents whatever arrived as the message body:
   
   - `web/src/pages/instance/message.tsx:959` renders 
`formatBody(selectedMsg.body)` inside a `copyable` `Paragraph` under the 消息体 
heading, with no marker of any kind;
   - `web/src/pages/instance/message.tsx:731` saves `formatBody(record.body)` 
as `${record.msgId}.json` with `type: 'application/json'`.
   
   Two concrete operator-facing failures follow:
   
   1. **A truncated body reads as a complete one.** Query a 5 MiB JSON message 
and the panel shows the first 64 KiB, pretty-printed, in a monospace block with 
a copy button, and the download writes a `.json` file. The JSON is cut 
mid-token, so anyone who copies or downloads it gets a file that does not 
parse, with nothing on screen explaining why. The natural conclusion - "this 
producer is writing malformed JSON" - is wrong.
   2. **A binary body is shown as text.** For a protobuf, gzip or otherwise 
non-UTF-8 payload the panel shows base64 in a block styled for JSON, and the 
download names it `.json`. `formatBody` (`:140`) tries `JSON.parse` first, so 
the operator gets an unexplained wall of base64 rather than the statement "this 
is not text".
   
   The repository already has the right idiom for exactly this situation on the 
DLQ page: `web/src/pages/instance/dlq.tsx:917`-`:923` renders 
属性过多或单值过长,服务端已截断展示 whenever `propertiesTruncated` is set, and `DLQMessage` 
declares that field (`web/src/api/message.ts:123`). The message page is the one 
place the flags are dropped.
   
   #4777 fixed the copy/download path to preserve the received body verbatim 
and explicitly scoped this out: "It does not recover backend-truncated or 
encoded data." This report is that remaining half - not recovering the data 
(the server never sent it) but stopping the UI from implying it did.
   
   ### Steps to Reproduce
   
   1. Against a self-managed cluster, send a message whose body is larger than 
64 KiB (a big JSON document is enough), and a second message whose body is 
binary (any non-UTF-8 bytes).
   2. Console -> 消息查询, pick the topic, query by Message ID, and open 详情 on the 
large message.
   3. Read the 消息体 block, then click 下载.
   4. Repeat for the binary message.
   
   ### What Did You Expect to See?
   
   The panel to state what the server already reported: that the body was cut 
at the display limit, so what is shown, copied and downloaded is incomplete; 
and, for the binary message, that the body is not UTF-8 text and is being shown 
base64-encoded. The same treatment the DLQ page gives `propertiesTruncated`.
   
   ### What Did You See Instead?
   
   A complete-looking, pretty-printed body with no truncation marker, and a 
base64 blob presented as if it were the message text. Both download as 
`<msgId>.json` with `Content-Type: application/json`. The `bodyEncoding` and 
`bodyTruncated` values the server computed are present in the HTTP response and 
discarded by the frontend type.
   
   ### Additional Context
   
   Fix scope: declare `bodyEncoding` and `bodyTruncated` on `MessageRecord`, 
render a truncation warning and a binary-body notice above the 消息体 block in the 
detail panel, add the two zh/en strings under `web/src/i18n/`, and pin both 
with tests in `web/src/pages/instance/__tests__/MessagePage.test.tsx` - one 
that fails if either notice disappears, one that fails if a complete UTF-8 body 
starts showing warnings.
   
   Deliberately left out of this report, so the fix stays reviewable:
   
   - the detail panel shows no message **properties** at all, so 
`propertiesTruncated` has nothing to annotate yet; adding a properties table 
(with the DLQ page's truncation note) is a separate change
   - the download filename and MIME type for a base64 body (`.json` / 
`application/json`) - that is #4777's area
   - `storeTime: number | string` on the same interface, which papers over the 
mock layer using ISO strings while `MessageRecordVO.storeTime` is a `long` and 
§8.1 documents the field as `number` (`:1338`)
   
   ### Are You Willing to Submit a Pull Request?
   
   - [x] Yes, I am willing to submit a pull request.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to