mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
StackAssertion cause is now in extraData
This commit is contained in:
parent
2bbd9b017f
commit
b0db0a5f78
@ -99,7 +99,7 @@ export async function sendEmail({
|
||||
html
|
||||
}));
|
||||
} catch (error) {
|
||||
const extraData = { host: emailConfig.host, from: emailConfig.senderEmail, to, subject };
|
||||
const extraData = { host: emailConfig.host, from: emailConfig.senderEmail, to, subject, cause: error };
|
||||
const temporaryErrorIndicators = [
|
||||
"450 ",
|
||||
"Client network socket disconnected before secure TLS connection was established",
|
||||
@ -113,7 +113,7 @@ export async function sendEmail({
|
||||
}
|
||||
|
||||
// TODO if using custom email config, we should notify the developer instead of throwing an error
|
||||
throw new StackAssertionError('Failed to send email', extraData, { cause: error });
|
||||
throw new StackAssertionError('Failed to send email', extraData);
|
||||
}
|
||||
}, 3, { exponentialDelayBase: 2000 }));
|
||||
} finally {
|
||||
|
||||
@ -125,7 +125,7 @@ export async function logEvent<T extends EventType[]>(
|
||||
data = await eventType.dataSchema.validate(data, { strict: true, stripUnknown: false });
|
||||
} catch (error) {
|
||||
if (error instanceof yup.ValidationError) {
|
||||
throw new StackAssertionError(`Invalid event data for event type: ${eventType.id}`, { eventType, data, error, originalData, originalEventTypes: eventTypes }, { cause: error });
|
||||
throw new StackAssertionError(`Invalid event data for event type: ${eventType.id}`, { eventType, data, error, originalData, originalEventTypes: eventTypes, cause: error });
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ export abstract class OAuthBaseProvider {
|
||||
if (error?.error === 'access_denied') {
|
||||
throw new KnownErrors.OAuthProviderAccessDenied();
|
||||
}
|
||||
throw new StackAssertionError(`Inner OAuth callback failed due to error: ${error}`, undefined, { cause: error });
|
||||
throw new StackAssertionError(`Inner OAuth callback failed due to error: ${error}`, { cause: error });
|
||||
}
|
||||
|
||||
tokenSet = processTokenSet(this.constructor.name, tokenSet, this.defaultAccessTokenExpiresInMillis);
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import "../polyfills";
|
||||
|
||||
import * as yup from "yup";
|
||||
import { SmartRouteHandler, routeHandlerTypeHelper, createSmartRouteHandler } from "./smart-route-handler";
|
||||
import { CrudSchema, CrudTypeOf, CrudlOperation } from "@stackframe/stack-shared/dist/crud";
|
||||
import { FilterUndefined } from "@stackframe/stack-shared/dist/utils/objects";
|
||||
import { typedIncludes } from "@stackframe/stack-shared/dist/utils/arrays";
|
||||
import { deindent, typedToLowercase } from "@stackframe/stack-shared/dist/utils/strings";
|
||||
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { SmartRequestAuth } from "./smart-request";
|
||||
import { ProjectsCrud } from "@stackframe/stack-shared/dist/interface/crud/projects";
|
||||
import { UsersCrud } from "@stackframe/stack-shared/dist/interface/crud/users";
|
||||
import { yupArray, yupBoolean, yupMixed, yupNumber, yupObject, yupString, yupValidate } from "@stackframe/stack-shared/dist/schema-fields";
|
||||
import { ProjectsCrud } from "@stackframe/stack-shared/dist/interface/crud/projects";
|
||||
import { typedIncludes } from "@stackframe/stack-shared/dist/utils/arrays";
|
||||
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { FilterUndefined } from "@stackframe/stack-shared/dist/utils/objects";
|
||||
import { deindent, typedToLowercase } from "@stackframe/stack-shared/dist/utils/strings";
|
||||
import * as yup from "yup";
|
||||
import { SmartRequestAuth } from "./smart-request";
|
||||
import { SmartRouteHandler, createSmartRouteHandler, routeHandlerTypeHelper } from "./smart-route-handler";
|
||||
|
||||
type GetAdminKey<T extends CrudTypeOf<any>, K extends Capitalize<CrudlOperation>> = K extends keyof T["Admin"] ? T["Admin"][K] : void;
|
||||
|
||||
@ -292,8 +292,7 @@ async function validate<T>(obj: unknown, schema: yup.ISchema<T>, currentUser: Us
|
||||
Errors:
|
||||
${error.errors.join("\n")}
|
||||
`,
|
||||
{ obj: JSON.stringify(obj), schema },
|
||||
{ cause: error }
|
||||
{ obj: JSON.stringify(obj), schema, cause: error },
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
|
||||
@ -61,7 +61,7 @@ async function validate<T>(obj: SmartRequest, schema: yup.Schema<T>, req: NextRe
|
||||
if (error instanceof yup.ValidationError) {
|
||||
if (req === null) {
|
||||
// we weren't called by a HTTP request, so it must be a logical error in a manual invocation
|
||||
throw new StackAssertionError("Request validation failed", {}, { cause: error });
|
||||
throw new StackAssertionError("Request validation failed", { cause: error });
|
||||
} else {
|
||||
const inners = error.inner.length ? error.inner : [error];
|
||||
const description = schema.describe();
|
||||
|
||||
@ -45,7 +45,7 @@ async function validate<T>(req: NextRequest | null, obj: unknown, schema: yup.Sc
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
throw new StackAssertionError(`Error occurred during ${req ? `${req.method} ${req.url}` : "a custom endpoint invocation's"} response validation: ${error}`, { obj, schema, error }, { cause: error });
|
||||
throw new StackAssertionError(`Error occurred during ${req ? `${req.method} ${req.url}` : "a custom endpoint invocation's"} response validation: ${error}`, { obj, schema, cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { globalVar } from "./globals";
|
||||
import { Json } from "./json";
|
||||
import { pick } from "./objects";
|
||||
|
||||
|
||||
export function throwErr(errorMessage: string, extraData?: any): never;
|
||||
@ -62,26 +63,21 @@ export function concatStacktraces(first: Error, ...errors: Error[]): void {
|
||||
}
|
||||
|
||||
|
||||
export class StackAssertionError extends Error implements ErrorWithCustomCapture {
|
||||
constructor(message: string, public readonly extraData?: Record<string, any>, options?: ErrorOptions) {
|
||||
export class StackAssertionError extends Error {
|
||||
constructor(message: string, public readonly extraData?: Record<string, any> & ErrorOptions) {
|
||||
const disclaimer = `\n\nThis is likely an error in Stack. Please make sure you are running the newest version and report it.`;
|
||||
super(`${message}${message.endsWith(disclaimer) ? "" : disclaimer}`, options);
|
||||
}
|
||||
super(`${message}${message.endsWith(disclaimer) ? "" : disclaimer}`, pick(extraData ?? {}, ["cause"]));
|
||||
|
||||
customCaptureExtraArgs = [
|
||||
{
|
||||
...this.extraData,
|
||||
...this.cause ? { cause: this.cause } : {},
|
||||
},
|
||||
];
|
||||
Object.defineProperty(this, "customCaptureExtraArgs", {
|
||||
get() {
|
||||
return [this.extraData];
|
||||
},
|
||||
enumerable: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
StackAssertionError.prototype.name = "StackAssertionError";
|
||||
|
||||
|
||||
export type ErrorWithCustomCapture = {
|
||||
customCaptureExtraArgs: any[],
|
||||
};
|
||||
|
||||
const errorSinks = new Set<(location: string, error: unknown, ...extraArgs: unknown[]) => void>();
|
||||
export function registerErrorSink(sink: (location: string, error: unknown) => void): void {
|
||||
if (errorSinks.has(sink)) {
|
||||
@ -182,7 +178,7 @@ export class StatusError extends Error {
|
||||
super(message);
|
||||
this.statusCode = status;
|
||||
if (!message) {
|
||||
throw new StackAssertionError("StatusError always requires a message unless a Status object is passed", {}, { cause: this });
|
||||
throw new StackAssertionError("StatusError always requires a message unless a Status object is passed", { cause: this });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user