MISC: Improve script args validation message (#2451)

This commit is contained in:
Michael Ficocelli
2026-01-18 14:34:49 -05:00
committed by GitHub
parent c55577929c
commit 19064a1b12
3 changed files with 54 additions and 20 deletions

View File

@@ -56,7 +56,7 @@ import { hasScriptExtension, ScriptFilePath } from "../Paths/ScriptFilePath";
import { CustomBoundary } from "../ui/Components/CustomBoundary";
import { ServerConstants } from "../Server/data/Constants";
import { errorMessage, log } from "./ErrorMessages";
import { assertStringWithNSContext, debugType } from "./TypeAssertion";
import { assertStringWithNSContext, debugType, userFriendlyString } from "./TypeAssertion";
import {
canAccessBitNodeFeature,
getDefaultBitNodeOptions,
@@ -64,6 +64,7 @@ import {
} from "../BitNode/BitNodeUtils";
import { JSONMap } from "../Types/Jsonable";
import { Settings } from "../Settings/Settings";
import { getFriendlyType } from "../utils/TypeAssertion";
export const helpers = {
string,
@@ -182,10 +183,31 @@ function positiveNumber(ctx: NetscriptContext, argName: string, v: unknown): Pos
}
return n;
}
function isScriptArg(arg: unknown): boolean {
return typeof arg === "string" || typeof arg === "number" || typeof arg === "boolean";
}
function isScriptArgs(args: unknown): args is ScriptArg[] {
return Array.isArray(args) && args.every(isScriptArg);
}
/** Returns args back if it is a ScriptArg[]. Throws an error if it is not. */
function scriptArgs(ctx: NetscriptContext, args: unknown) {
if (!isScriptArgs(args)) throw errorMessage(ctx, "'args' is not an array of script args", "TYPE");
return args;
function scriptArgs(ctx: NetscriptContext, args: unknown): ScriptArg[] {
if (isScriptArgs(args)) {
return args;
}
if (!Array.isArray(args)) {
throw errorMessage(ctx, `scriptArgs must be an array. Current type is ${getFriendlyType(args)}.`, "TYPE");
}
const nonValidArgument: unknown = args.find((arg) => !isScriptArg(arg));
throw errorMessage(
ctx,
`scriptArgs can only contain strings, numbers, or booleans.
Found ${getFriendlyType(nonValidArgument)}: ${userFriendlyString(nonValidArgument)}
Args passed: ${args.map((arg) => userFriendlyString(arg)).join(", ")}`,
"TYPE",
);
}
/** Converts the provided value for v to a boolean, throwing if it is not */
@@ -503,11 +525,6 @@ function getNormalServer(ctx: NetscriptContext, host: string): Server {
return server;
}
function isScriptArgs(args: unknown): args is ScriptArg[] {
const isScriptArg = (arg: unknown) => typeof arg === "string" || typeof arg === "number" || typeof arg === "boolean";
return Array.isArray(args) && args.every(isScriptArg);
}
function hack(ctx: NetscriptContext, hostname: string, manual: boolean, opts: unknown): Promise<number> {
const ws = ctx.workerScript;
const { threads, stock, additionalMsec } = validateHGWOptions(ctx, opts);

View File

@@ -1,19 +1,36 @@
import type { NetscriptContext } from "./APIWrapper";
import { errorMessage } from "./ErrorMessages";
const userFriendlyString = (v: unknown): string => {
const clip = (s: string): string => {
if (s.length > 15) return s.slice(0, 12) + "...";
return s;
};
if (typeof v === "number") return String(v);
const clip = (s: string): string => {
if (s.length > 15) {
return s.slice(0, 12) + "...";
}
return s;
};
export const userFriendlyString = (v: unknown): string => {
if (typeof v === "number") {
return String(v);
}
if (typeof v === "string") {
if (v === "") return "empty string";
if (v === "") {
return `'' (empty string)`;
}
return `'${clip(v)}'`;
}
const json = JSON.stringify(v);
if (!json) return "???";
return `'${clip(json)}'`;
// JSON.stringify does not handle undefined in arrays or objects well (e.g., [undefined] is stringified to [null]). We
// accept this drawback.
let stringValue = JSON.stringify(v);
if (!stringValue) {
if (typeof v === "function") {
// Special case for function.
stringValue = "(function)";
} else {
// Special case for undefined and Symbol.
stringValue = String(v);
}
}
return clip(stringValue);
};
export const debugType = (v: unknown): string => {

View File

@@ -35,7 +35,7 @@ export function assert<T>(
}
/** Returns the friendlyType of v. arrays are "array" and null is "null". */
function getFriendlyType(v: unknown): string {
export function getFriendlyType(v: unknown): string {
return v === null ? "null" : Array.isArray(v) ? "array" : typeof v;
}