diff --git a/deno-runtime/handlers/listener/handler.ts b/deno-runtime/handlers/listener/handler.ts index 6c3d3dc32..7fb79ee74 100644 --- a/deno-runtime/handlers/listener/handler.ts +++ b/deno-runtime/handlers/listener/handler.ts @@ -1,14 +1,18 @@ import { Defined, JsonRpcError } from 'jsonrpc-lite'; import type { App } from '@rocket.chat/apps-engine/definition/App.ts'; +import type { IMessage } from "@rocket.chat/apps-engine/definition/messages/IMessage.ts"; +import type { IRoom } from "@rocket.chat/apps-engine/definition/rooms/IRoom.ts"; +import type { AppsEngineException as _AppsEngineException } from '@rocket.chat/apps-engine/definition/exceptions/AppsEngineException.ts'; import { AppObjectRegistry } from '../../AppObjectRegistry.ts'; import { MessageExtender } from "../../lib/accessors/extenders/MessageExtender.ts"; -import { IMessage } from "@rocket.chat/apps-engine/definition/messages/IMessage.ts"; -import { IRoom } from "@rocket.chat/apps-engine/definition/rooms/IRoom.ts"; import { RoomExtender } from "../../lib/accessors/extenders/RoomExtender.ts"; import { MessageBuilder } from "../../lib/accessors/builders/MessageBuilder.ts"; import { RoomBuilder } from "../../lib/accessors/builders/RoomBuilder.ts"; import { AppAccessorsInstance } from "../../lib/accessors/mod.ts"; +import { require } from '../../lib/require.ts'; + +const { AppsEngineException } = require('@rocket.chat/apps-engine/definition/exceptions/AppsEgnineException') as { AppsEngineException: typeof _AppsEngineException }; export default async function handleListener(method: string, params: unknown): Promise { const [, evtInterface] = method.split(':'); @@ -18,11 +22,11 @@ export default async function handleListener(method: string, params: unknown): P const eventExecutor = app?.[evtInterface as keyof App]; if (typeof eventExecutor !== 'function') { - return new JsonRpcError('Invalid event interface called on app', -32000); + return JsonRpcError.methodNotFound({ message: 'Invalid event interface called on app' }); } if (!Array.isArray(params) || params.length < 1 || params.length > 2) { - return new JsonRpcError('Invalid params', -32602); + return JsonRpcError.invalidParams(null); } try { @@ -33,7 +37,11 @@ export default async function handleListener(method: string, params: unknown): P return e; } - return JsonRpcError.internalError(e.message); + if (e instanceof AppsEngineException) { + return new JsonRpcError(e.message, AppsEngineException.JSONRPC_ERROR_CODE, { name: e.name }); + } + + return JsonRpcError.internalError({ message: e.message }); } } @@ -45,7 +53,7 @@ function parseArgs(evtInterface: string, params: unknown[]): unknown[] { const [param1, param2] = params as [unknown, unknown]; if (!param1) { - throw new JsonRpcError('Invalid params', -32000); + throw JsonRpcError.invalidParams(null); } const args: unknown[] = [param1, AppAccessorsInstance.getReader(), AppAccessorsInstance.getHttp()]; @@ -91,7 +99,7 @@ function parseArgs(evtInterface: string, params: unknown[]): unknown[] { // This guy gets an extra one if (evtInterface === 'executePostMessageDeleted') { if (!param2) { - throw new JsonRpcError('Invalid params', -32000); + throw JsonRpcError.invalidParams(null); } args.push(param2); diff --git a/deno-runtime/lib/messenger.ts b/deno-runtime/lib/messenger.ts index 88409abf9..92941461a 100644 --- a/deno-runtime/lib/messenger.ts +++ b/deno-runtime/lib/messenger.ts @@ -1,7 +1,7 @@ import * as jsonrpc from 'jsonrpc-lite'; -import { AppObjectRegistry } from "../AppObjectRegistry.ts"; -import type { Logger } from './logger.ts' +import { AppObjectRegistry } from '../AppObjectRegistry.ts'; +import type { Logger } from './logger.ts'; export type RequestDescriptor = Pick; @@ -29,8 +29,8 @@ export function isErrorResponse(message: jsonrpc.JsonRpc): message is jsonrpc.Er const encoder = new TextEncoder(); export const RPCResponseObserver = new EventTarget(); -export const Transport = new class Transporter { - private selectedTransport: Transporter["stdoutTransport"] | Transporter["noopTransport"]; +export const Transport = new (class Transporter { + private selectedTransport: Transporter['stdoutTransport'] | Transporter['noopTransport']; constructor() { this.selectedTransport = this.stdoutTransport.bind(this); @@ -41,7 +41,7 @@ export const Transport = new class Transporter { await Deno.stdout.write(encoded); } - private async noopTransport(_message: jsonrpc.JsonRpc): Promise { } + private async noopTransport(_message: jsonrpc.JsonRpc): Promise {} public selectTransport(transport: 'stdout' | 'noop'): void { switch (transport) { @@ -57,7 +57,7 @@ export const Transport = new class Transporter { public send(message: jsonrpc.JsonRpc): Promise { return this.selectedTransport(message); } -} +})(); export function parseMessage(message: string) { const parsed = jsonrpc.parse(message); diff --git a/src/definition/exceptions/AppsEngineException.ts b/src/definition/exceptions/AppsEngineException.ts index 510b5314d..a3e802aa6 100644 --- a/src/definition/exceptions/AppsEngineException.ts +++ b/src/definition/exceptions/AppsEngineException.ts @@ -14,6 +14,8 @@ export class AppsEngineException extends Error { public name = 'AppsEngineException'; + public static JSONRPC_ERROR_CODE = -32070; + public message: string; constructor(message?: string) { diff --git a/src/server/ProxiedApp.ts b/src/server/ProxiedApp.ts index c53976b21..80f21abf0 100644 --- a/src/server/ProxiedApp.ts +++ b/src/server/ProxiedApp.ts @@ -1,5 +1,6 @@ import type { IAppAccessors, ILogger } from '../definition/accessors'; import { AppStatus } from '../definition/AppStatus'; +import { AppsEngineException } from '../definition/exceptions'; import type { IApp } from '../definition/IApp'; import type { IAppAuthorInfo, IAppInfo } from '../definition/metadata'; import { AppMethod } from '../definition/metadata'; @@ -55,7 +56,13 @@ export class ProxiedApp implements IApp { } public async call(method: `${AppMethod}`, ...args: Array): Promise { - return this.appRuntime.sendRequest({ method: `app:${method}`, params: args }); + try { + return await this.appRuntime.sendRequest({ method: `app:${method}`, params: args }); + } catch (e) { + if (e.code === AppsEngineException.JSONRPC_ERROR_CODE) { + throw new AppsEngineException(e.message); + } + } } public getStatus(): AppStatus {