Skip to content

Remove enums from core api #622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Microsoft Azure Functions NodeJS Worker",
"license": "(MIT OR Apache-2.0)",
"dependencies": {
"@azure/functions": "^3.5.0-alpha.2",
"@azure/functions": "^3.5.0-alpha.3",
"@grpc/grpc-js": "^1.2.7",
"@grpc/proto-loader": "^0.6.4",
"blocked-at": "^1.2.0",
Expand Down
8 changes: 4 additions & 4 deletions src/LegacyFunctionLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

import { FunctionCallback } from '@azure/functions-core';
import { AzureFunctionsRpcMessages as rpc } from '../azure-functions-language-worker-protobuf/src/rpc';
import { AzFuncSystemError } from './errors';
import { loadScriptFile } from './loadScriptFile';
import { PackageJson } from './parsers/parsePackageJson';
import { InternalException } from './utils/InternalException';
import { nonNullProp } from './utils/nonNull';
import { RegisteredFunction } from './WorkerChannel';

Expand Down Expand Up @@ -40,7 +40,7 @@ export class LegacyFunctionLoader implements ILegacyFunctionLoader {
callback: loadedFunction.callback.bind(loadedFunction.thisArg),
};
} else {
throw new InternalException(`Function code for '${functionId}' is not loaded and cannot be invoked.`);
throw new AzFuncSystemError(`Function code for '${functionId}' is not loaded and cannot be invoked.`);
}
}
}
Expand Down Expand Up @@ -72,9 +72,9 @@ function getEntryPoint(f: any, entryPoint?: string): [FunctionCallback, unknown]
'If multiple functions are exported, ' +
"you must indicate the entry point, either by naming it 'run' or 'index', or by naming it " +
"explicitly via the 'entryPoint' metadata property.";
throw new InternalException(msg);
throw new AzFuncSystemError(msg);
} else if (typeof f !== 'function') {
throw new InternalException(
throw new AzFuncSystemError(
'The resolved entry point is not a function and cannot be invoked by the functions runtime. Make sure the function has been correctly exported.'
);
}
Expand Down
9 changes: 4 additions & 5 deletions src/Worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
// Licensed under the MIT License.

import * as parseArgs from 'minimist';
import { AzFuncSystemError, ensureErrorType } from './errors';
import { CreateGrpcEventStream } from './GrpcClient';
import { LegacyFunctionLoader } from './LegacyFunctionLoader';
import { setupCoreModule } from './setupCoreModule';
import { setupEventStream } from './setupEventStream';
import { startBlockedMonitor } from './utils/blockedMonitor';
import { ensureErrorType } from './utils/ensureErrorType';
import { InternalException } from './utils/InternalException';
import { systemError, systemLog } from './utils/Logger';
import { isEnvironmentVariableSet } from './utils/util';
import { WorkerChannel } from './WorkerChannel';
Expand All @@ -27,7 +26,7 @@ export function startNodeWorker(args) {
if (!requestId) debugInfo.push(`'requestId' is ${requestId}`);
if (!grpcMaxMessageLength) debugInfo.push(`'grpcMaxMessageLength' is ${grpcMaxMessageLength}`);

throw new InternalException(`gRPC client connection info is missing or incorrect (${debugInfo.join(', ')}).`);
throw new AzFuncSystemError(`gRPC client connection info is missing or incorrect (${debugInfo.join(', ')}).`);
}

const connection = `${host}:${port}`;
Expand All @@ -38,7 +37,7 @@ export function startNodeWorker(args) {
eventStream = CreateGrpcEventStream(connection, parseInt(grpcMaxMessageLength));
} catch (err) {
const error = ensureErrorType(err);
error.isAzureFunctionsInternalException = true;
error.isAzureFunctionsSystemError = true;
error.message = 'Error creating GRPC event stream: ' + error.message;
throw error;
}
Expand All @@ -57,7 +56,7 @@ export function startNodeWorker(args) {
process.on('uncaughtException', (err: unknown) => {
const error = ensureErrorType(err);
let errorMessage: string;
if (error.isAzureFunctionsInternalException) {
if (error.isAzureFunctionsSystemError) {
errorMessage = `Worker ${workerId} uncaught exception: ${error.stack || err}`;
} else {
errorMessage = `Worker ${workerId} uncaught exception (learn more: https://go.microsoft.com/fwlink/?linkid=2097909 ): ${
Expand Down
6 changes: 3 additions & 3 deletions src/WorkerChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import { FunctionCallback, HookCallback, HookContext, HookData, ProgrammingModel } from '@azure/functions-core';
import { AzureFunctionsRpcMessages as rpc } from '../azure-functions-language-worker-protobuf/src/rpc';
import { Disposable } from './Disposable';
import { AzFuncRangeError, AzFuncSystemError, ensureErrorType } from './errors';
import { IEventStream } from './GrpcClient';
import { ILegacyFunctionLoader } from './LegacyFunctionLoader';
import { PackageJson, parsePackageJson } from './parsers/parsePackageJson';
import { ensureErrorType } from './utils/ensureErrorType';
import LogLevel = rpc.RpcLog.Level;
import LogCategory = rpc.RpcLog.RpcLogCategory;

Expand All @@ -27,7 +27,7 @@ export class WorkerChannel {

get hostVersion(): string {
if (!this._hostVersion) {
throw new Error('Trying to access hostVersion before it is set.');
throw new AzFuncSystemError('Cannot access hostVersion before worker init');
} else {
return this._hostVersion;
}
Expand Down Expand Up @@ -116,7 +116,7 @@ export class WorkerChannel {
case 'appTerminate':
return this.#appTerminateHooks;
default:
throw new RangeError(`Unrecognized hook "${hookName}"`);
throw new AzFuncRangeError(`Unrecognized hook "${hookName}"`);
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/coreApi/converters/ensureKeysMatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

/**
* Removes some unnecessary properties that may have been set to `undefined` during conversion
*/
export function ensureKeysMatch<TData, TResult>(data: TData, result: TResult): TResult {
for (const key of Object.keys(result)) {
if (!(key in data)) {
delete result[key];
}
}
return result;
}
76 changes: 76 additions & 0 deletions src/coreApi/converters/fromCoreFunctionMetadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

import * as coreTypes from '@azure/functions-core';
import { AzureFunctionsRpcMessages as rpc } from '../../../azure-functions-language-worker-protobuf/src/rpc';
import { ensureKeysMatch } from './ensureKeysMatch';
import { fromCoreStatusResult } from './fromCoreStatusResult';
import { handleDefaultEnumCase } from './handleDefaultEnumCase';

export function fromCoreFunctionMetadata(data: coreTypes.RpcFunctionMetadata): rpc.IRpcFunctionMetadata {
const result = {
...data,
bindings: fromCoreBindings(data.bindings),
status: fromCoreStatusResult(data.status),
};
return ensureKeysMatch(data, result);
}

function fromCoreBindings(
data: { [key: string]: coreTypes.RpcBindingInfo } | null | undefined
): { [key: string]: rpc.IBindingInfo } | null | undefined {
if (data) {
const result = {};
for (const [key, value] of Object.entries(data)) {
result[key] = fromCoreBinding(value);
}
return ensureKeysMatch(data, result);
} else {
return data;
}
}

function fromCoreBinding(data: coreTypes.RpcBindingInfo | null | undefined): rpc.IBindingInfo | null | undefined {
if (data) {
const result = {
...data,
dataType: fromCoreBindingDataType(data.dataType),
direction: fromCoreBindingDirection(data.direction),
};
return ensureKeysMatch(data, result);
} else {
return data;
}
}

function fromCoreBindingDataType(
data: coreTypes.RpcBindingDataType | null | undefined
): rpc.BindingInfo.DataType | null | undefined {
switch (data) {
case 'binary':
return rpc.BindingInfo.DataType.binary;
case 'stream':
return rpc.BindingInfo.DataType.stream;
case 'string':
return rpc.BindingInfo.DataType.string;
case 'undefined':
return rpc.BindingInfo.DataType.undefined;
default:
return handleDefaultEnumCase(data, 'CoreRpcBindingDataType');
}
}

function fromCoreBindingDirection(
data: coreTypes.RpcBindingDirection | null | undefined
): rpc.BindingInfo.Direction | null | undefined {
switch (data) {
case 'in':
return rpc.BindingInfo.Direction.in;
case 'inout':
return rpc.BindingInfo.Direction.inout;
case 'out':
return rpc.BindingInfo.Direction.out;
default:
return handleDefaultEnumCase(data, 'CoreRpcBindingDirection');
}
}
36 changes: 36 additions & 0 deletions src/coreApi/converters/fromCoreInvocationResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

import * as coreTypes from '@azure/functions-core';
import { AzureFunctionsRpcMessages as rpc } from '../../../azure-functions-language-worker-protobuf/src/rpc';
import { ensureKeysMatch } from './ensureKeysMatch';
import { fromCoreStatusResult } from './fromCoreStatusResult';
import { fromCoreTypedData } from './fromCoreTypedData';

export function fromCoreInvocationResponse(data: coreTypes.RpcInvocationResponse): rpc.IInvocationResponse {
const result = {
...data,
outputData: fromCoreParameterBindings(data.outputData),
result: fromCoreStatusResult(data.result),
returnValue: fromCoreTypedData(data.returnValue),
};
return ensureKeysMatch(data, result);
}

function fromCoreParameterBindings(
data: coreTypes.RpcParameterBinding[] | null | undefined
): rpc.IParameterBinding[] | null | undefined {
if (data) {
return data.map(fromCoreParameterBinding);
} else {
return data;
}
}

function fromCoreParameterBinding(data: coreTypes.RpcParameterBinding): rpc.IParameterBinding {
const result = {
...data,
data: fromCoreTypedData(data.data),
};
return ensureKeysMatch(data, result);
}
88 changes: 88 additions & 0 deletions src/coreApi/converters/fromCoreStatusResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License.

import * as coreTypes from '@azure/functions-core';
import { AzureFunctionsRpcMessages as rpc } from '../../../azure-functions-language-worker-protobuf/src/rpc';
import { ensureKeysMatch } from './ensureKeysMatch';
import { handleDefaultEnumCase } from './handleDefaultEnumCase';

export function fromCoreStatusResult(
data: coreTypes.RpcStatusResult | null | undefined
): rpc.IStatusResult | null | undefined {
if (data) {
const result = {
...data,
logs: fromCoreLogs(data.logs),
status: fromCoreStatus(data.status),
};
return ensureKeysMatch(data, result);
} else {
return data;
}
}

function fromCoreLogs(data: coreTypes.RpcLog[] | null | undefined): rpc.IRpcLog[] | null | undefined {
if (data) {
return data.map(fromCoreLog);
} else {
return data;
}
}

function fromCoreLog(data: coreTypes.RpcLog): rpc.IRpcLog {
const result = {
...data,
level: fromCoreLogLevel(data.level),
logCategory: fromCoreLogCategory(data.logCategory),
};
return ensureKeysMatch(data, result);
}

export function fromCoreLogLevel(data: coreTypes.RpcLogLevel | null | undefined): rpc.RpcLog.Level | null | undefined {
switch (data) {
case 'critical':
return rpc.RpcLog.Level.Critical;
case 'debug':
return rpc.RpcLog.Level.Debug;
case 'error':
return rpc.RpcLog.Level.Error;
case 'information':
return rpc.RpcLog.Level.Information;
case 'none':
return rpc.RpcLog.Level.None;
case 'trace':
return rpc.RpcLog.Level.Trace;
case 'warning':
return rpc.RpcLog.Level.Warning;
default:
return handleDefaultEnumCase(data, 'CoreRpcLogLevel');
}
}

export function fromCoreLogCategory(
data: coreTypes.RpcLogCategory | null | undefined
): rpc.RpcLog.RpcLogCategory | null | undefined {
switch (data) {
case 'customMetric':
return rpc.RpcLog.RpcLogCategory.CustomMetric;
case 'system':
return rpc.RpcLog.RpcLogCategory.System;
case 'user':
return rpc.RpcLog.RpcLogCategory.User;
default:
return handleDefaultEnumCase(data, 'CoreRpcLogCategory');
}
}

function fromCoreStatus(data: coreTypes.RpcStatus | null | undefined): rpc.StatusResult.Status | null | undefined {
switch (data) {
case 'cancelled':
return rpc.StatusResult.Status.Cancelled;
case 'failure':
return rpc.StatusResult.Status.Failure;
case 'success':
return rpc.StatusResult.Status.Success;
default:
return handleDefaultEnumCase(data, 'CoreRpcStatus');
}
}
Loading