OptionalcauseOptional ReadonlyCodeError code from the first GraphQL error, e.g. JWT_EXPIRED.
Optional ReadonlyrequestOriginating request, narrowed to the query document. See the note above on casing.
Optional ReadonlyresponseServer response, narrowed to status and GraphQL errors.
NAMING: response and request are intentionally camelCase, against MJ's
PascalCase convention for public members. They exist to mirror the shape of
the upstream ClientError this replaces, and downstream code reads them by
those exact names — err?.response?.errors in the workspace initializer, the
Bootstrap initialization service, and the DevTools GraphQL console. Renaming
them would break the compatibility that is this class's entire purpose.
Members that are new here, rather than inherited from the upstream surface,
follow the MJ convention below.
OptionalstackOptional ReadonlyVariableShape of the withheld variables — key names and value types, never values.
StaticstackThe Error.stackTraceLimit property specifies the number of stack frames
collected by a stack trace (whether generated by new Error().stack or
Error.captureStackTrace(obj)).
The default value is 10 but may be set to any valid JavaScript number. Changes
will affect any stack trace captured after the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will not capture any frames.
StaticcaptureCreates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
OptionalconstructorOpt: FunctionStaticprepare
The error
ExecuteGQLrethrows in place of the raw client error.Sanitising only the log line is not enough to close the leak.
ExecuteGQLrethrows, and its callers catch and log —LogError(e)appears 19 times in this package alone, and there are ~178ExecuteGQLcall sites across the repo. Every one of those receives an error whosemessageandstackstill contain the serialised request, and any of them may stringify it. Redacting at one log statement fixes one log statement; replacing the propagated object fixes all of them at once, including callers not yet written.What is preserved, and why it is safe:
response.status/response.errors— the server's diagnosis of the failure. Every known downstream consumer reads exactly these (andextensions.code).request.query— the static document, which binds values but contains none.What is dropped:
request.variables— the caller's payload, where secrets live.response.data— a partial success on a credential-bearing read could return decrypted values here, so it is not forwarded.messageandstack, both of which embed the serialised request.nameis preserved from the original (e.g.ClientError) so code that branches on the error's name keeps working.