Skip to content

Commit

Permalink
feat(MethodCallValidator): add method not found error
Browse files Browse the repository at this point in the history
fixes #156
  • Loading branch information
BelfordZ committed Jun 25, 2019
1 parent 2e64de6 commit 95fd0d6
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/index-web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ export {
OpenRPCDocumentValidationError,
OpenRPCDocumentDereferencingError,
ContentDescriptorNotFoundInMethodError,
};
};
10 changes: 9 additions & 1 deletion src/method-call-validator/method-call-validator.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import MethodCallValidator from "./method-call-validator";
import { OpenRPC } from "@open-rpc/meta-schema";
import MethodCallParameterValidationError from "./parameter-validation-error";
import MethodCallMethodNotFoundError from "./method-not-found-error";

const getExampleSchema = (): OpenRPC => ({
info: { title: "123", version: "1" },
Expand Down Expand Up @@ -46,7 +47,7 @@ describe("MethodCallValidator", () => {
it("returns array of errors if invalid", () => {
const example = getExampleSchema() as any;
const methodCallValidator = new MethodCallValidator(example);
const result = methodCallValidator.validate("foo", [123]);
const result = methodCallValidator.validate("foo", [123]) as MethodCallParameterValidationError[];
expect(result.length).toBe(1);
expect(result[0]).toBeInstanceOf(MethodCallParameterValidationError);
});
Expand All @@ -58,4 +59,11 @@ describe("MethodCallValidator", () => {
expect(result).toEqual([]);
});

it("returns method not found error when the method name is invalid", () => {
const example = getExampleSchema() as any;
const methodCallValidator = new MethodCallValidator(example);
const result = methodCallValidator.validate("boo", ["123"]);
expect(result).toBeInstanceOf(MethodCallMethodNotFoundError);
});

});
11 changes: 10 additions & 1 deletion src/method-call-validator/method-call-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as _ from "lodash";
import { generateMethodParamId } from "../generate-method-id";
import MethodCallParameterValidationError from "./parameter-validation-error";
import { OpenRPC, MethodObject, ContentDescriptorObject } from "@open-rpc/meta-schema";
import MethodCallMethodNotFoundError from "./method-not-found-error";

/**
* A class to assist in validating method calls to an OpenRPC-based service. Generated Clients,
Expand Down Expand Up @@ -46,6 +47,7 @@ export default class MethodCallValidator {
* @param params the param values that you want validated.
*
* @returns an array of parameter validation errors, or if there are none, an empty array.
* if the method name is invalid, a [[MethodCallMethodNotFoundError]] is returned.
*
* @example
* ```typescript
Expand All @@ -57,9 +59,16 @@ export default class MethodCallValidator {
* ```
*
*/
public validate(methodName: string, params: any[]): MethodCallParameterValidationError[] {
public validate(
methodName: string,
params: any[],
): MethodCallParameterValidationError[] | MethodCallMethodNotFoundError {
const method = _.find(this.document.methods, { name: methodName }) as MethodObject;

if (!method) {
return new MethodCallMethodNotFoundError(methodName, this.document, params);
}

if (method.params === undefined) {
return [];
}
Expand Down
49 changes: 49 additions & 0 deletions src/method-call-validator/method-not-found-error.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import MethodCallMethodNotFoundError from "./method-not-found-error";
import { OpenRPC } from "@open-rpc/meta-schema";

const exampleDoc = {
info: {
title: "testerino",
version: "123",
},
methods: [],
openrpc: "1.1.9",
} as OpenRPC;

describe("MethodCallMethodNotFoundError", () => {
it("can be instantiated", () => {
const error = new MethodCallMethodNotFoundError("floobar", exampleDoc, ["abc", 123]);
expect(error).toBeInstanceOf(MethodCallMethodNotFoundError);
});

it("works when no params passed", () => {
const error = new MethodCallMethodNotFoundError("floobar", exampleDoc);
expect(error).toBeInstanceOf(MethodCallMethodNotFoundError);
});

it("properly parses params in to a string", () => {
const error = new MethodCallMethodNotFoundError("floobar", exampleDoc, ["abc", { abc: 123 }, 123]);
expect(error).toBeInstanceOf(MethodCallMethodNotFoundError);
expect(error.message).toBe(`Method Not Found Error for OpenRPC API named "testerino"
The requested method: "floobar" not a valid method.
debug info:
params: "abc", {"abc":123}, 123`);
});

it("it handles openrpc docs with a method", () => {
exampleDoc.methods = [
{
name: "dooptiedoo",
params: [],
result: {
name: "dooptie",
schema: {},
},
},
];
const error = new MethodCallMethodNotFoundError("floobar", exampleDoc, ["abc", { abc: 123 }, 123]);
expect(error).toBeInstanceOf(MethodCallMethodNotFoundError);
expect(error.message).toContain("Valid method names are as follows: dooptiedoo");
});
});
44 changes: 44 additions & 0 deletions src/method-call-validator/method-not-found-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { OpenRPC } from "@open-rpc/meta-schema";

/**
* Provides an error interface for handling when a method is trying to be called but does not exist.
*/
export default class MethodCallMethodNotFoundError implements Error {
public name = "MethodCallMethodNotFoundError";
public message: string;

/**
* @param methodName The method name that was used.
* @param openrpcDocument The OpenRPC document that the method was used against.
* @param receievedParams The params, if any, that were used.
*/
constructor(
public methodName: string,
public openrpcDocument: OpenRPC,
public receievedParams: any[] = [],
) {
const msg = [
`Method Not Found Error for OpenRPC API named "${openrpcDocument.info.title}"`,
`The requested method: "${methodName}" not a valid method.`,

];

if (openrpcDocument.methods.length > 0) {
msg.push(
`Valid method names are as follows: ${openrpcDocument.methods.map(({ name }) => name).join(", ")}`,
);
}

if (receievedParams.length > 0) {
const stringedParams = receievedParams
.map((p) => { try { return JSON.stringify(p); } catch (e) { return p; } })
.join(", ");

msg.push("");
msg.push("debug info:");
msg.push(` params: ${stringedParams}`);
}

this.message = msg.join("\n");
}
}
2 changes: 1 addition & 1 deletion src/method-call-validator/parameter-validation-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Schema } from "@open-rpc/meta-schema";
* Provides an error interface for handling when a function call has invalid parameters.
*/
export default class MethodCallParameterValidationError implements Error {
public name = "OpenRPCDocumentDereferencingError";
public name = "MethodCallParameterValidationError";
public message: string;

/**
Expand Down

0 comments on commit 95fd0d6

Please # to comment.