Skip to content

Commit

Permalink
Refactor some error handling and the AppsEngineException for listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
d-gubert committed Dec 29, 2023
1 parent d5109e0 commit 39ed757
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 14 deletions.
22 changes: 15 additions & 7 deletions deno-runtime/handlers/listener/handler.ts
Original file line number Diff line number Diff line change
@@ -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<Defined | JsonRpcError> {
const [, evtInterface] = method.split(':');
Expand All @@ -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 {
Expand All @@ -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 });
}
}

Expand All @@ -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()];
Expand Down Expand Up @@ -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);
Expand Down
12 changes: 6 additions & 6 deletions deno-runtime/lib/messenger.ts
Original file line number Diff line number Diff line change
@@ -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<jsonrpc.RequestObject, 'method' | 'params'>;

Expand Down Expand Up @@ -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);
Expand All @@ -41,7 +41,7 @@ export const Transport = new class Transporter {
await Deno.stdout.write(encoded);
}

private async noopTransport(_message: jsonrpc.JsonRpc): Promise<void> { }
private async noopTransport(_message: jsonrpc.JsonRpc): Promise<void> {}

public selectTransport(transport: 'stdout' | 'noop'): void {
switch (transport) {
Expand All @@ -57,7 +57,7 @@ export const Transport = new class Transporter {
public send(message: jsonrpc.JsonRpc): Promise<void> {
return this.selectedTransport(message);
}
}
})();

export function parseMessage(message: string) {
const parsed = jsonrpc.parse(message);
Expand Down
2 changes: 2 additions & 0 deletions src/definition/exceptions/AppsEngineException.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
export class AppsEngineException extends Error {
public name = 'AppsEngineException';

public static JSONRPC_ERROR_CODE = -32070;

public message: string;

constructor(message?: string) {
Expand Down
9 changes: 8 additions & 1 deletion src/server/ProxiedApp.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -55,7 +56,13 @@ export class ProxiedApp implements IApp {
}

public async call(method: `${AppMethod}`, ...args: Array<any>): Promise<any> {
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 {
Expand Down

0 comments on commit 39ed757

Please sign in to comment.