Fixed issue when a variable passed to Request flow could be undefined (#55)

This commit is contained in:
Pavel 2021-06-09 20:39:04 +03:00 committed by GitHub
parent 67a1f91961
commit cabbe89845
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 5 deletions

View File

@ -2,6 +2,7 @@ import { checkConnection, createClient, FluenceClient } from '../../FluenceClien
import Multiaddr from 'multiaddr';
import { nodes } from '../connection';
import { RequestFlowBuilder } from '../../internal/RequestFlowBuilder';
import log from 'loglevel';
let client: FluenceClient;
@ -245,6 +246,29 @@ describe('Typescript usage suite', () => {
});
});
it('Should not crash if undefined is passed as a variable', async () => {
// arrange
client = await createClient();
const [request, promise] = new RequestFlowBuilder()
.withRawScript(
`
(seq
(call %init_peer_id% ("op" "identity") [arg] res)
(call %init_peer_id% ("return" "return") [res])
)
`,
)
.withVariable('arg', undefined as any)
.buildAsFetch<any[]>('return', 'return');
// act
await client.initiateFlow(request);
const [res] = await promise;
// assert
expect(res).toBe(null);
});
it('Should throw correct error when the client tries to send a particle not to the relay', async () => {
// arrange
client = await createClient();

View File

@ -53,7 +53,7 @@ export interface CallServiceData {
/**
* Type for all the possible ovjects that can be return to the AVM
*/
export type CallServiceResultType = object | boolean | number | string;
export type CallServiceResultType = object | boolean | number | string | null;
/**
* Represents the result of the `call` air instruction to be returned into AVM

View File

@ -207,6 +207,13 @@ export class ClientImpl implements FluenceClient {
},
});
if (res.result === undefined) {
log.error(
`Call to serviceId=${serviceId} fnName=${fnName} unexpectedly returned undefined result, falling back to null`,
);
res.result = null;
}
return {
ret_code: res.retCode,
result: JSON.stringify(res.result),

View File

@ -1,5 +1,5 @@
import log from 'loglevel';
import { CallServiceHandler } from './CallServiceHandler';
import { CallServiceHandler, CallServiceResultType } from './CallServiceHandler';
import { DEFAULT_TTL, RequestFlow } from './RequestFlow';
export const loadVariablesService = 'load';
@ -100,7 +100,7 @@ export class RequestFlowBuilder {
private shouldInjectRelay: boolean = true;
private ttl: number = DEFAULT_TTL;
private variables = new Map<string, any>();
private variables = new Map<string, CallServiceResultType>();
private handlerConfigs: Array<(handler: CallServiceHandler, request: RequestFlow) => void> = [];
private buildScriptActions: Array<(sb: ScriptBuilder) => void> = [];
private onTimeout: () => void;
@ -268,7 +268,7 @@ export class RequestFlowBuilder {
/**
* Adds a variable to the list of injected variables
*/
withVariable(name: string, value: any): RequestFlowBuilder {
withVariable(name: string, value: CallServiceResultType): RequestFlowBuilder {
this.variables.set(name, value);
return this;
}
@ -277,7 +277,9 @@ export class RequestFlowBuilder {
* Adds a multiple variable to the list of injected variables.
* Variables can be specified in form of either object or a map where keys correspond to variable names
*/
withVariables(data: Map<string, any> | Record<string, any>): RequestFlowBuilder {
withVariables(
data: Map<string, CallServiceResultType> | Record<string, CallServiceResultType>,
): RequestFlowBuilder {
if (data instanceof Map) {
this.variables = new Map([...Array.from(this.variables.entries()), ...Array.from(data.entries())]);
} else {