executePreMessageSentModify failes
opened this issue · comments
I am trying to modify a message before it is send, but I get the following error in the logs.
Is this a problem of my code, or is the error in the apps-engine?
"{"stack":"TypeError: Converting circular structure to JSON\n --> starting at object with constructor 'Timeout'\n | property '_idlePrev' -> object with constructor 'TimersList'\n --- property '_idleNext' closes the circle\n at JSON.stringify ()\n at /snap/rocketchat-server/1442/programs/server/npm/node_modules/@rocket.chat/apps-engine/server/logging/AppConsole.js:64:34\n at Array.map ()\n at AppConsole.addEntry (/snap/rocketchat-server/1442/programs/server/npm/node_modules/@rocket.chat/apps-engine/server/logging/AppConsole.js:56:25)\n at AppConsole.debug (/snap/rocketchat-server/1442/programs/server/npm/node_modules/@rocket.chat/apps-engine/server/logging/AppConsole.js:23:14)\n at ProxiedApp. (/snap/rocketchat-server/1442/programs/server/npm/node_modules/@rocket.chat/apps-engine/server/ProxiedApp.js:74:24)\n at Generator.next ()\n at fulfilled (/snap/rocketchat-server/1442/programs/server/npm/node_modules/@rocket.chat/apps-engine/server/ProxiedApp.js:4:58)\n at /snap/rocketchat-server/1442/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/fiber_pool.js:43:40","message":"Converting circular structure to JSON\n --> starting at object with constructor 'Timeout'\n | property '_idlePrev' -> object with constructor 'TimersList'\n --- property '_idleNext' closes the circle"}"
Name | Version |
---|---|
RC Version | 3.6.2 |
Apps Engine Version | 1.17.0 |
"@types/node": "^14.11.2",
"@rocket.chat/apps-engine": "^1.4.0", //(1.18 didn't work either)
"typescript": "^2.9.1"
Do you have your source code anywhere? Looks like you're trying to convert something to json and it's actually a circular javascript object that references itself or objects in it reference each other. I'd venture to say it is your code but can't say for sure.
Sure ;)
The slash command seems to work fine, so here the code of the edit
code
import {
IConfigurationExtend,
IEnvironmentRead,
IHttp,
ILogger,
IMessageBuilder,
IPersistence,
IRead,
} from "@rocket.chat/apps-engine/definition/accessors";
import { App } from "@rocket.chat/apps-engine/definition/App";
import { IMessage, IPreMessageSentModify } from "@rocket.chat/apps-engine/definition/messages";
import { IAppInfo } from "@rocket.chat/apps-engine/definition/metadata";
import { MyCommand } from "./MyCommand";
export class MyApp extends App implements IPreMessageSentModify {
private matcher: RegExp = /(^|\ )#(\d+)(\s|$)/g;
constructor(info: IAppInfo, logger: ILogger) {
super(info, logger);
}
public async checkPreMessageSentModify(
message: IMessage,
read: IRead,
http: IHttp,
): Promise<boolean> {
if (typeof message.text !== "string") {
return false;
}
const result = message.text.match(this.matcher);
return result ? result.length !== 0 : false;
}
public async executePreMessageSentModify(
message: IMessage,
builder: IMessageBuilder,
read: IRead,
http: IHttp,
persistence: IPersistence,
): Promise<IMessage> {
if (typeof message.text !== "string") {
return message;
}
const mylink = message.text.match(this.matcher);
if (mylink && mylink.length > 0) {
for (const link of mylink) {
const parts = this.matcher.exec(link);
if (!parts || parts.length < 1) {
continue;
}
const newLink = `[${link}](someDifferentLink/${parts[0]})`;
message.text = message.text.replace(link, newLink);
}
}
return message;
}
protected async extendConfiguration(
configuration: IConfigurationExtend,
environmentRead: IEnvironmentRead,
): Promise<void> {
await configuration.slashCommands.provideSlashCommand(new MyCommand());
}
}
@d-gubert @lolimay any idea about this? From what I can see at a quick glance, nothing stands out about his code that would cause the error.
Hey! Yeah, this does look like a bug on the Apps-Engine. It happens because the app's logger logs the value returned by your method, and breaks when it has a circular dependency in it. The "more correct™️" way to handle this event would be to actually use the builder: IMessageBuilder
param to modify whatever information you want in your message, and then return a builder.getMessage()
in the end - this message will not have the circular dependency.
It does have some justification to it: the message: IMessage
parameter you receive in your executePreMessageSentModify
is actually a frozen message object, and any modifications to it are silently ignored, because you should be using the builder
instead.
That said, this behavior is for sure not intuitive and prone to cause confusion. We should have it better documented.
@d-gubert thank you very much. That worked
by the way, I copied the code from @graywolf336's repo, is it there wrong as well?
Thanks for the fast resolution :D
do you want this issue to stay open as reminder to update the documentation?