mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
chore: rename fundamentals to base (#9119)
This commit is contained in:
595
packages/backend/server/src/base/error/def.ts
Normal file
595
packages/backend/server/src/base/error/def.ts
Normal file
@@ -0,0 +1,595 @@
|
||||
import { STATUS_CODES } from 'node:http';
|
||||
|
||||
import { HttpStatus, Logger } from '@nestjs/common';
|
||||
import { capitalize } from 'lodash-es';
|
||||
|
||||
export type UserFriendlyErrorBaseType =
|
||||
| 'bad_request'
|
||||
| 'too_many_requests'
|
||||
| 'resource_not_found'
|
||||
| 'resource_already_exists'
|
||||
| 'invalid_input'
|
||||
| 'action_forbidden'
|
||||
| 'no_permission'
|
||||
| 'quota_exceeded'
|
||||
| 'authentication_required'
|
||||
| 'internal_server_error';
|
||||
|
||||
type ErrorArgType = 'string' | 'number' | 'boolean';
|
||||
type ErrorArgs = Record<string, ErrorArgType | Record<string, ErrorArgType>>;
|
||||
|
||||
export type UserFriendlyErrorOptions = {
|
||||
type: UserFriendlyErrorBaseType;
|
||||
args?: ErrorArgs;
|
||||
message: string | ((args: any) => string);
|
||||
};
|
||||
|
||||
const BaseTypeToHttpStatusMap: Record<UserFriendlyErrorBaseType, HttpStatus> = {
|
||||
too_many_requests: HttpStatus.TOO_MANY_REQUESTS,
|
||||
bad_request: HttpStatus.BAD_REQUEST,
|
||||
resource_not_found: HttpStatus.NOT_FOUND,
|
||||
resource_already_exists: HttpStatus.BAD_REQUEST,
|
||||
invalid_input: HttpStatus.BAD_REQUEST,
|
||||
action_forbidden: HttpStatus.FORBIDDEN,
|
||||
no_permission: HttpStatus.FORBIDDEN,
|
||||
quota_exceeded: HttpStatus.PAYMENT_REQUIRED,
|
||||
authentication_required: HttpStatus.UNAUTHORIZED,
|
||||
internal_server_error: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
};
|
||||
|
||||
const IncludedEvents = new Set([
|
||||
// email
|
||||
'invalid_email',
|
||||
'email_token_not_found',
|
||||
'invalid_email_token',
|
||||
'email_already_used',
|
||||
'same_email_provided',
|
||||
// magic link
|
||||
'action_forbidden',
|
||||
'link_expired',
|
||||
'email_verification_required',
|
||||
// oauth
|
||||
'missing_oauth_query_parameter',
|
||||
'unknown_oauth_provider',
|
||||
'invalid_oauth_callback_state',
|
||||
'oauth_state_expired',
|
||||
'oauth_account_already_connected',
|
||||
]);
|
||||
|
||||
export class UserFriendlyError extends Error {
|
||||
/**
|
||||
* Standard HTTP status code
|
||||
*/
|
||||
status: number;
|
||||
|
||||
/**
|
||||
* Business error category, for example 'resource_already_exists' or 'quota_exceeded'
|
||||
*/
|
||||
type: string;
|
||||
|
||||
/**
|
||||
* Additional data that could be used for error handling or formatting
|
||||
*/
|
||||
data: any;
|
||||
|
||||
constructor(
|
||||
type: UserFriendlyErrorBaseType,
|
||||
name: keyof typeof USER_FRIENDLY_ERRORS,
|
||||
message?: string | ((args?: any) => string),
|
||||
args?: any
|
||||
) {
|
||||
const defaultMsg = USER_FRIENDLY_ERRORS[name].message;
|
||||
// disallow message override for `internal_server_error`
|
||||
// to avoid leak internal information to user
|
||||
let msg =
|
||||
name === 'internal_server_error' ? defaultMsg : (message ?? defaultMsg);
|
||||
|
||||
if (typeof msg === 'function') {
|
||||
msg = msg(args);
|
||||
}
|
||||
|
||||
super(msg);
|
||||
this.status = BaseTypeToHttpStatusMap[type];
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.data = args;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
status: this.status,
|
||||
code: STATUS_CODES[this.status] ?? 'BAD REQUEST',
|
||||
type: this.type.toUpperCase(),
|
||||
name: this.name.toUpperCase(),
|
||||
message: this.message,
|
||||
data: this.data,
|
||||
};
|
||||
}
|
||||
|
||||
toText() {
|
||||
const json = this.toJSON();
|
||||
return [
|
||||
`Status: ${json.status}`,
|
||||
`Type: ${json.type}`,
|
||||
`Name: ${json.name}`,
|
||||
`Message: ${json.message}`,
|
||||
`Data: ${JSON.stringify(json.data)}`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
log(context: string) {
|
||||
// ignore all user behavior error log
|
||||
if (
|
||||
this.type !== 'internal_server_error' &&
|
||||
!IncludedEvents.has(this.name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
new Logger(context).error(
|
||||
'Internal server error',
|
||||
this.cause ? ((this.cause as any).stack ?? this.cause) : this.stack
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ObjectType()
|
||||
* export class XXXDataType {
|
||||
* @Field()
|
||||
*
|
||||
* }
|
||||
*/
|
||||
function generateErrorArgs(name: string, args: ErrorArgs) {
|
||||
const typeName = `${name}DataType`;
|
||||
const lines = [`@ObjectType()`, `class ${typeName} {`];
|
||||
Object.entries(args).forEach(([arg, fieldArgs]) => {
|
||||
if (typeof fieldArgs === 'object') {
|
||||
const subResult = generateErrorArgs(
|
||||
name + 'Field' + capitalize(arg),
|
||||
fieldArgs
|
||||
);
|
||||
lines.unshift(subResult.def);
|
||||
lines.push(
|
||||
` @Field(() => ${subResult.name}) ${arg}!: ${subResult.name};`
|
||||
);
|
||||
} else {
|
||||
lines.push(` @Field() ${arg}!: ${fieldArgs}`);
|
||||
}
|
||||
});
|
||||
|
||||
lines.push('}');
|
||||
|
||||
return { name: typeName, def: lines.join('\n') };
|
||||
}
|
||||
|
||||
export function generateUserFriendlyErrors() {
|
||||
const output = [
|
||||
'/* eslint-disable */',
|
||||
'// AUTO GENERATED FILE',
|
||||
`import { createUnionType, Field, ObjectType, registerEnumType } from '@nestjs/graphql';`,
|
||||
'',
|
||||
`import { UserFriendlyError } from './def';`,
|
||||
];
|
||||
|
||||
const errorNames: string[] = [];
|
||||
const argTypes: string[] = [];
|
||||
|
||||
for (const code in USER_FRIENDLY_ERRORS) {
|
||||
errorNames.push(code.toUpperCase());
|
||||
// @ts-expect-error allow
|
||||
const options: UserFriendlyErrorOptions = USER_FRIENDLY_ERRORS[code];
|
||||
const className = code
|
||||
.split('_')
|
||||
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
||||
.join('');
|
||||
|
||||
const args = options.args
|
||||
? generateErrorArgs(className, options.args)
|
||||
: null;
|
||||
|
||||
const classDef = `
|
||||
export class ${className} extends UserFriendlyError {
|
||||
constructor(${args ? `args: ${args.name}, ` : ''}message?: string${args ? ` | ((args: ${args.name}) => string)` : ''}) {
|
||||
super('${options.type}', '${code}', message${args ? ', args' : ''});
|
||||
}
|
||||
}`;
|
||||
|
||||
if (args) {
|
||||
output.push(args.def);
|
||||
argTypes.push(args.name);
|
||||
}
|
||||
output.push(classDef);
|
||||
}
|
||||
|
||||
output.push(`export enum ErrorNames {
|
||||
${errorNames.join(',\n ')}
|
||||
}
|
||||
registerEnumType(ErrorNames, {
|
||||
name: 'ErrorNames'
|
||||
})
|
||||
|
||||
export const ErrorDataUnionType = createUnionType({
|
||||
name: 'ErrorDataUnion',
|
||||
types: () =>
|
||||
[${argTypes.join(', ')}] as const,
|
||||
});
|
||||
`);
|
||||
|
||||
return output.join('\n');
|
||||
}
|
||||
|
||||
// DEFINE ALL USER FRIENDLY ERRORS HERE
|
||||
export const USER_FRIENDLY_ERRORS = {
|
||||
// Internal uncaught errors
|
||||
internal_server_error: {
|
||||
type: 'internal_server_error',
|
||||
message: 'An internal error occurred.',
|
||||
},
|
||||
too_many_request: {
|
||||
type: 'too_many_requests',
|
||||
message: 'Too many requests.',
|
||||
},
|
||||
not_found: {
|
||||
type: 'resource_not_found',
|
||||
message: 'Resource not found.',
|
||||
},
|
||||
|
||||
// User Errors
|
||||
user_not_found: {
|
||||
type: 'resource_not_found',
|
||||
message: 'User not found.',
|
||||
},
|
||||
user_avatar_not_found: {
|
||||
type: 'resource_not_found',
|
||||
message: 'User avatar not found.',
|
||||
},
|
||||
email_already_used: {
|
||||
type: 'resource_already_exists',
|
||||
message: 'This email has already been registered.',
|
||||
},
|
||||
same_email_provided: {
|
||||
type: 'invalid_input',
|
||||
message:
|
||||
'You are trying to update your account email to the same as the old one.',
|
||||
},
|
||||
wrong_sign_in_credentials: {
|
||||
type: 'invalid_input',
|
||||
args: { email: 'string' },
|
||||
message: ({ email }) => `Wrong user email or password: ${email}`,
|
||||
},
|
||||
unknown_oauth_provider: {
|
||||
type: 'invalid_input',
|
||||
args: { name: 'string' },
|
||||
message: ({ name }) => `Unknown authentication provider ${name}.`,
|
||||
},
|
||||
oauth_state_expired: {
|
||||
type: 'bad_request',
|
||||
message: 'OAuth state expired, please try again.',
|
||||
},
|
||||
invalid_oauth_callback_state: {
|
||||
type: 'bad_request',
|
||||
message: 'Invalid callback state parameter.',
|
||||
},
|
||||
missing_oauth_query_parameter: {
|
||||
type: 'bad_request',
|
||||
args: { name: 'string' },
|
||||
message: ({ name }) => `Missing query parameter \`${name}\`.`,
|
||||
},
|
||||
oauth_account_already_connected: {
|
||||
type: 'bad_request',
|
||||
message:
|
||||
'The third-party account has already been connected to another user.',
|
||||
},
|
||||
invalid_email: {
|
||||
type: 'invalid_input',
|
||||
args: { email: 'string' },
|
||||
message: ({ email }) => `An invalid email provided: ${email}`,
|
||||
},
|
||||
invalid_password_length: {
|
||||
type: 'invalid_input',
|
||||
args: { min: 'number', max: 'number' },
|
||||
message: ({ min, max }) =>
|
||||
`Password must be between ${min} and ${max} characters`,
|
||||
},
|
||||
password_required: {
|
||||
type: 'invalid_input',
|
||||
message: 'Password is required.',
|
||||
},
|
||||
wrong_sign_in_method: {
|
||||
type: 'invalid_input',
|
||||
message:
|
||||
'You are trying to sign in by a different method than you signed up with.',
|
||||
},
|
||||
early_access_required: {
|
||||
type: 'action_forbidden',
|
||||
message: `You don't have early access permission. Visit https://community.affine.pro/c/insider-general/ for more information.`,
|
||||
},
|
||||
sign_up_forbidden: {
|
||||
type: 'action_forbidden',
|
||||
message: `You are not allowed to sign up.`,
|
||||
},
|
||||
email_token_not_found: {
|
||||
type: 'invalid_input',
|
||||
message: 'The email token provided is not found.',
|
||||
},
|
||||
invalid_email_token: {
|
||||
type: 'invalid_input',
|
||||
message: 'An invalid email token provided.',
|
||||
},
|
||||
link_expired: {
|
||||
type: 'bad_request',
|
||||
message: 'The link has expired.',
|
||||
},
|
||||
|
||||
// Authentication & Permission Errors
|
||||
authentication_required: {
|
||||
type: 'authentication_required',
|
||||
message: 'You must sign in first to access this resource.',
|
||||
},
|
||||
action_forbidden: {
|
||||
type: 'action_forbidden',
|
||||
message: 'You are not allowed to perform this action.',
|
||||
},
|
||||
access_denied: {
|
||||
type: 'no_permission',
|
||||
message: 'You do not have permission to access this resource.',
|
||||
},
|
||||
email_verification_required: {
|
||||
type: 'action_forbidden',
|
||||
message: 'You must verify your email before accessing this resource.',
|
||||
},
|
||||
|
||||
// Workspace & Userspace & Doc & Sync errors
|
||||
space_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { spaceId: 'string' },
|
||||
message: ({ spaceId }) => `Space ${spaceId} not found.`,
|
||||
},
|
||||
not_in_space: {
|
||||
type: 'action_forbidden',
|
||||
args: { spaceId: 'string' },
|
||||
message: ({ spaceId }) =>
|
||||
`You should join in Space ${spaceId} before broadcasting messages.`,
|
||||
},
|
||||
already_in_space: {
|
||||
type: 'action_forbidden',
|
||||
args: { spaceId: 'string' },
|
||||
message: ({ spaceId }) => `You have already joined in Space ${spaceId}.`,
|
||||
},
|
||||
space_access_denied: {
|
||||
type: 'no_permission',
|
||||
args: { spaceId: 'string' },
|
||||
message: ({ spaceId }) =>
|
||||
`You do not have permission to access Space ${spaceId}.`,
|
||||
},
|
||||
space_owner_not_found: {
|
||||
type: 'internal_server_error',
|
||||
args: { spaceId: 'string' },
|
||||
message: ({ spaceId }) => `Owner of Space ${spaceId} not found.`,
|
||||
},
|
||||
cant_change_space_owner: {
|
||||
type: 'action_forbidden',
|
||||
message: 'You are not allowed to change the owner of a Space.',
|
||||
},
|
||||
doc_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { spaceId: 'string', docId: 'string' },
|
||||
message: ({ spaceId, docId }) =>
|
||||
`Doc ${docId} under Space ${spaceId} not found.`,
|
||||
},
|
||||
doc_access_denied: {
|
||||
type: 'no_permission',
|
||||
args: { spaceId: 'string', docId: 'string' },
|
||||
message: ({ spaceId, docId }) =>
|
||||
`You do not have permission to access doc ${docId} under Space ${spaceId}.`,
|
||||
},
|
||||
version_rejected: {
|
||||
type: 'action_forbidden',
|
||||
args: { version: 'string', serverVersion: 'string' },
|
||||
message: ({ version, serverVersion }) =>
|
||||
`Your client with version ${version} is rejected by remote sync server. Please upgrade to ${serverVersion}.`,
|
||||
},
|
||||
invalid_history_timestamp: {
|
||||
type: 'invalid_input',
|
||||
args: { timestamp: 'string' },
|
||||
message: 'Invalid doc history timestamp provided.',
|
||||
},
|
||||
doc_history_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { spaceId: 'string', docId: 'string', timestamp: 'number' },
|
||||
message: ({ spaceId, docId, timestamp }) =>
|
||||
`History of ${docId} at ${timestamp} under Space ${spaceId}.`,
|
||||
},
|
||||
blob_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { spaceId: 'string', blobId: 'string' },
|
||||
message: ({ spaceId, blobId }) =>
|
||||
`Blob ${blobId} not found in Space ${spaceId}.`,
|
||||
},
|
||||
expect_to_publish_page: {
|
||||
type: 'invalid_input',
|
||||
message: 'Expected to publish a page, not a Space.',
|
||||
},
|
||||
expect_to_revoke_public_page: {
|
||||
type: 'invalid_input',
|
||||
message: 'Expected to revoke a public page, not a Space.',
|
||||
},
|
||||
page_is_not_public: {
|
||||
type: 'bad_request',
|
||||
message: 'Page is not public.',
|
||||
},
|
||||
failed_to_save_updates: {
|
||||
type: 'internal_server_error',
|
||||
message: 'Failed to store doc updates.',
|
||||
},
|
||||
failed_to_upsert_snapshot: {
|
||||
type: 'internal_server_error',
|
||||
message: 'Failed to store doc snapshot.',
|
||||
},
|
||||
|
||||
// Subscription Errors
|
||||
unsupported_subscription_plan: {
|
||||
type: 'invalid_input',
|
||||
args: { plan: 'string' },
|
||||
message: ({ plan }) => `Unsupported subscription plan: ${plan}.`,
|
||||
},
|
||||
failed_to_checkout: {
|
||||
type: 'internal_server_error',
|
||||
message: 'Failed to create checkout session.',
|
||||
},
|
||||
invalid_checkout_parameters: {
|
||||
type: 'invalid_input',
|
||||
message: 'Invalid checkout parameters provided.',
|
||||
},
|
||||
subscription_already_exists: {
|
||||
type: 'resource_already_exists',
|
||||
args: { plan: 'string' },
|
||||
message: ({ plan }) => `You have already subscribed to the ${plan} plan.`,
|
||||
},
|
||||
invalid_subscription_parameters: {
|
||||
type: 'invalid_input',
|
||||
message: 'Invalid subscription parameters provided.',
|
||||
},
|
||||
subscription_not_exists: {
|
||||
type: 'resource_not_found',
|
||||
args: { plan: 'string' },
|
||||
message: ({ plan }) => `You didn't subscribe to the ${plan} plan.`,
|
||||
},
|
||||
subscription_has_been_canceled: {
|
||||
type: 'action_forbidden',
|
||||
message: 'Your subscription has already been canceled.',
|
||||
},
|
||||
subscription_has_not_been_canceled: {
|
||||
type: 'action_forbidden',
|
||||
message: 'Your subscription has not been canceled.',
|
||||
},
|
||||
subscription_expired: {
|
||||
type: 'action_forbidden',
|
||||
message: 'Your subscription has expired.',
|
||||
},
|
||||
same_subscription_recurring: {
|
||||
type: 'bad_request',
|
||||
args: { recurring: 'string' },
|
||||
message: ({ recurring }) =>
|
||||
`Your subscription has already been in ${recurring} recurring state.`,
|
||||
},
|
||||
customer_portal_create_failed: {
|
||||
type: 'internal_server_error',
|
||||
message: 'Failed to create customer portal session.',
|
||||
},
|
||||
subscription_plan_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { plan: 'string', recurring: 'string' },
|
||||
message: 'You are trying to access a unknown subscription plan.',
|
||||
},
|
||||
cant_update_onetime_payment_subscription: {
|
||||
type: 'action_forbidden',
|
||||
message: 'You cannot update an onetime payment subscription.',
|
||||
},
|
||||
workspace_id_required_for_team_subscription: {
|
||||
type: 'invalid_input',
|
||||
message: 'A workspace is required to checkout for team subscription.',
|
||||
},
|
||||
workspace_id_required_to_update_team_subscription: {
|
||||
type: 'invalid_input',
|
||||
message: 'Workspace id is required to update team subscription.',
|
||||
},
|
||||
|
||||
// Copilot errors
|
||||
copilot_session_not_found: {
|
||||
type: 'resource_not_found',
|
||||
message: `Copilot session not found.`,
|
||||
},
|
||||
copilot_session_deleted: {
|
||||
type: 'action_forbidden',
|
||||
message: `Copilot session has been deleted.`,
|
||||
},
|
||||
no_copilot_provider_available: {
|
||||
type: 'internal_server_error',
|
||||
message: `No copilot provider available.`,
|
||||
},
|
||||
copilot_failed_to_generate_text: {
|
||||
type: 'internal_server_error',
|
||||
message: `Failed to generate text.`,
|
||||
},
|
||||
copilot_failed_to_create_message: {
|
||||
type: 'internal_server_error',
|
||||
message: `Failed to create chat message.`,
|
||||
},
|
||||
unsplash_is_not_configured: {
|
||||
type: 'internal_server_error',
|
||||
message: `Unsplash is not configured.`,
|
||||
},
|
||||
copilot_action_taken: {
|
||||
type: 'action_forbidden',
|
||||
message: `Action has been taken, no more messages allowed.`,
|
||||
},
|
||||
copilot_message_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { messageId: 'string' },
|
||||
message: ({ messageId }) => `Copilot message ${messageId} not found.`,
|
||||
},
|
||||
copilot_prompt_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { name: 'string' },
|
||||
message: ({ name }) => `Copilot prompt ${name} not found.`,
|
||||
},
|
||||
copilot_prompt_invalid: {
|
||||
type: 'invalid_input',
|
||||
message: `Copilot prompt is invalid.`,
|
||||
},
|
||||
copilot_provider_side_error: {
|
||||
type: 'internal_server_error',
|
||||
args: { provider: 'string', kind: 'string', message: 'string' },
|
||||
message: ({ provider, kind, message }) =>
|
||||
`Provider ${provider} failed with ${kind} error: ${message || 'unknown'}`,
|
||||
},
|
||||
|
||||
// Quota & Limit errors
|
||||
blob_quota_exceeded: {
|
||||
type: 'quota_exceeded',
|
||||
message: 'You have exceeded your blob storage quota.',
|
||||
},
|
||||
member_quota_exceeded: {
|
||||
type: 'quota_exceeded',
|
||||
message: 'You have exceeded your workspace member quota.',
|
||||
},
|
||||
copilot_quota_exceeded: {
|
||||
type: 'quota_exceeded',
|
||||
message:
|
||||
'You have reached the limit of actions in this workspace, please upgrade your plan.',
|
||||
},
|
||||
|
||||
// Config errors
|
||||
runtime_config_not_found: {
|
||||
type: 'resource_not_found',
|
||||
args: { key: 'string' },
|
||||
message: ({ key }) => `Runtime config ${key} not found.`,
|
||||
},
|
||||
invalid_runtime_config_type: {
|
||||
type: 'invalid_input',
|
||||
args: { key: 'string', want: 'string', get: 'string' },
|
||||
message: ({ key, want, get }) =>
|
||||
`Invalid runtime config type for '${key}', want '${want}', but get ${get}.`,
|
||||
},
|
||||
mailer_service_is_not_configured: {
|
||||
type: 'internal_server_error',
|
||||
message: 'Mailer service is not configured.',
|
||||
},
|
||||
cannot_delete_all_admin_account: {
|
||||
type: 'action_forbidden',
|
||||
message: 'Cannot delete all admin accounts.',
|
||||
},
|
||||
cannot_delete_own_account: {
|
||||
type: 'action_forbidden',
|
||||
message: 'Cannot delete own account.',
|
||||
},
|
||||
|
||||
// captcha errors
|
||||
captcha_verification_failed: {
|
||||
type: 'bad_request',
|
||||
message: 'Captcha verification failed.',
|
||||
},
|
||||
} satisfies Record<string, UserFriendlyErrorOptions>;
|
||||
678
packages/backend/server/src/base/error/errors.gen.ts
Normal file
678
packages/backend/server/src/base/error/errors.gen.ts
Normal file
@@ -0,0 +1,678 @@
|
||||
/* eslint-disable */
|
||||
// AUTO GENERATED FILE
|
||||
import { createUnionType, Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { UserFriendlyError } from './def';
|
||||
|
||||
export class InternalServerError extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'internal_server_error', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class TooManyRequest extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('too_many_requests', 'too_many_request', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class NotFound extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('resource_not_found', 'not_found', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class UserNotFound extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('resource_not_found', 'user_not_found', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class UserAvatarNotFound extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('resource_not_found', 'user_avatar_not_found', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class EmailAlreadyUsed extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('resource_already_exists', 'email_already_used', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class SameEmailProvided extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'same_email_provided', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class WrongSignInCredentialsDataType {
|
||||
@Field() email!: string
|
||||
}
|
||||
|
||||
export class WrongSignInCredentials extends UserFriendlyError {
|
||||
constructor(args: WrongSignInCredentialsDataType, message?: string | ((args: WrongSignInCredentialsDataType) => string)) {
|
||||
super('invalid_input', 'wrong_sign_in_credentials', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class UnknownOauthProviderDataType {
|
||||
@Field() name!: string
|
||||
}
|
||||
|
||||
export class UnknownOauthProvider extends UserFriendlyError {
|
||||
constructor(args: UnknownOauthProviderDataType, message?: string | ((args: UnknownOauthProviderDataType) => string)) {
|
||||
super('invalid_input', 'unknown_oauth_provider', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class OauthStateExpired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'oauth_state_expired', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidOauthCallbackState extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'invalid_oauth_callback_state', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class MissingOauthQueryParameterDataType {
|
||||
@Field() name!: string
|
||||
}
|
||||
|
||||
export class MissingOauthQueryParameter extends UserFriendlyError {
|
||||
constructor(args: MissingOauthQueryParameterDataType, message?: string | ((args: MissingOauthQueryParameterDataType) => string)) {
|
||||
super('bad_request', 'missing_oauth_query_parameter', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class OauthAccountAlreadyConnected extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'oauth_account_already_connected', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class InvalidEmailDataType {
|
||||
@Field() email!: string
|
||||
}
|
||||
|
||||
export class InvalidEmail extends UserFriendlyError {
|
||||
constructor(args: InvalidEmailDataType, message?: string | ((args: InvalidEmailDataType) => string)) {
|
||||
super('invalid_input', 'invalid_email', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class InvalidPasswordLengthDataType {
|
||||
@Field() min!: number
|
||||
@Field() max!: number
|
||||
}
|
||||
|
||||
export class InvalidPasswordLength extends UserFriendlyError {
|
||||
constructor(args: InvalidPasswordLengthDataType, message?: string | ((args: InvalidPasswordLengthDataType) => string)) {
|
||||
super('invalid_input', 'invalid_password_length', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class PasswordRequired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'password_required', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class WrongSignInMethod extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'wrong_sign_in_method', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class EarlyAccessRequired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'early_access_required', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class SignUpForbidden extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'sign_up_forbidden', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class EmailTokenNotFound extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'email_token_not_found', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidEmailToken extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'invalid_email_token', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class LinkExpired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'link_expired', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthenticationRequired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('authentication_required', 'authentication_required', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class ActionForbidden extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'action_forbidden', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class AccessDenied extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('no_permission', 'access_denied', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class EmailVerificationRequired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'email_verification_required', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SpaceNotFoundDataType {
|
||||
@Field() spaceId!: string
|
||||
}
|
||||
|
||||
export class SpaceNotFound extends UserFriendlyError {
|
||||
constructor(args: SpaceNotFoundDataType, message?: string | ((args: SpaceNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'space_not_found', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class NotInSpaceDataType {
|
||||
@Field() spaceId!: string
|
||||
}
|
||||
|
||||
export class NotInSpace extends UserFriendlyError {
|
||||
constructor(args: NotInSpaceDataType, message?: string | ((args: NotInSpaceDataType) => string)) {
|
||||
super('action_forbidden', 'not_in_space', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class AlreadyInSpaceDataType {
|
||||
@Field() spaceId!: string
|
||||
}
|
||||
|
||||
export class AlreadyInSpace extends UserFriendlyError {
|
||||
constructor(args: AlreadyInSpaceDataType, message?: string | ((args: AlreadyInSpaceDataType) => string)) {
|
||||
super('action_forbidden', 'already_in_space', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SpaceAccessDeniedDataType {
|
||||
@Field() spaceId!: string
|
||||
}
|
||||
|
||||
export class SpaceAccessDenied extends UserFriendlyError {
|
||||
constructor(args: SpaceAccessDeniedDataType, message?: string | ((args: SpaceAccessDeniedDataType) => string)) {
|
||||
super('no_permission', 'space_access_denied', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SpaceOwnerNotFoundDataType {
|
||||
@Field() spaceId!: string
|
||||
}
|
||||
|
||||
export class SpaceOwnerNotFound extends UserFriendlyError {
|
||||
constructor(args: SpaceOwnerNotFoundDataType, message?: string | ((args: SpaceOwnerNotFoundDataType) => string)) {
|
||||
super('internal_server_error', 'space_owner_not_found', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class CantChangeSpaceOwner extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'cant_change_space_owner', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class DocNotFoundDataType {
|
||||
@Field() spaceId!: string
|
||||
@Field() docId!: string
|
||||
}
|
||||
|
||||
export class DocNotFound extends UserFriendlyError {
|
||||
constructor(args: DocNotFoundDataType, message?: string | ((args: DocNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'doc_not_found', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class DocAccessDeniedDataType {
|
||||
@Field() spaceId!: string
|
||||
@Field() docId!: string
|
||||
}
|
||||
|
||||
export class DocAccessDenied extends UserFriendlyError {
|
||||
constructor(args: DocAccessDeniedDataType, message?: string | ((args: DocAccessDeniedDataType) => string)) {
|
||||
super('no_permission', 'doc_access_denied', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class VersionRejectedDataType {
|
||||
@Field() version!: string
|
||||
@Field() serverVersion!: string
|
||||
}
|
||||
|
||||
export class VersionRejected extends UserFriendlyError {
|
||||
constructor(args: VersionRejectedDataType, message?: string | ((args: VersionRejectedDataType) => string)) {
|
||||
super('action_forbidden', 'version_rejected', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class InvalidHistoryTimestampDataType {
|
||||
@Field() timestamp!: string
|
||||
}
|
||||
|
||||
export class InvalidHistoryTimestamp extends UserFriendlyError {
|
||||
constructor(args: InvalidHistoryTimestampDataType, message?: string | ((args: InvalidHistoryTimestampDataType) => string)) {
|
||||
super('invalid_input', 'invalid_history_timestamp', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class DocHistoryNotFoundDataType {
|
||||
@Field() spaceId!: string
|
||||
@Field() docId!: string
|
||||
@Field() timestamp!: number
|
||||
}
|
||||
|
||||
export class DocHistoryNotFound extends UserFriendlyError {
|
||||
constructor(args: DocHistoryNotFoundDataType, message?: string | ((args: DocHistoryNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'doc_history_not_found', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class BlobNotFoundDataType {
|
||||
@Field() spaceId!: string
|
||||
@Field() blobId!: string
|
||||
}
|
||||
|
||||
export class BlobNotFound extends UserFriendlyError {
|
||||
constructor(args: BlobNotFoundDataType, message?: string | ((args: BlobNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'blob_not_found', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExpectToPublishPage extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'expect_to_publish_page', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExpectToRevokePublicPage extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'expect_to_revoke_public_page', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class PageIsNotPublic extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'page_is_not_public', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class FailedToSaveUpdates extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'failed_to_save_updates', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class FailedToUpsertSnapshot extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'failed_to_upsert_snapshot', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class UnsupportedSubscriptionPlanDataType {
|
||||
@Field() plan!: string
|
||||
}
|
||||
|
||||
export class UnsupportedSubscriptionPlan extends UserFriendlyError {
|
||||
constructor(args: UnsupportedSubscriptionPlanDataType, message?: string | ((args: UnsupportedSubscriptionPlanDataType) => string)) {
|
||||
super('invalid_input', 'unsupported_subscription_plan', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class FailedToCheckout extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'failed_to_checkout', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidCheckoutParameters extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'invalid_checkout_parameters', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SubscriptionAlreadyExistsDataType {
|
||||
@Field() plan!: string
|
||||
}
|
||||
|
||||
export class SubscriptionAlreadyExists extends UserFriendlyError {
|
||||
constructor(args: SubscriptionAlreadyExistsDataType, message?: string | ((args: SubscriptionAlreadyExistsDataType) => string)) {
|
||||
super('resource_already_exists', 'subscription_already_exists', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidSubscriptionParameters extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'invalid_subscription_parameters', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SubscriptionNotExistsDataType {
|
||||
@Field() plan!: string
|
||||
}
|
||||
|
||||
export class SubscriptionNotExists extends UserFriendlyError {
|
||||
constructor(args: SubscriptionNotExistsDataType, message?: string | ((args: SubscriptionNotExistsDataType) => string)) {
|
||||
super('resource_not_found', 'subscription_not_exists', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class SubscriptionHasBeenCanceled extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'subscription_has_been_canceled', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class SubscriptionHasNotBeenCanceled extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'subscription_has_not_been_canceled', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class SubscriptionExpired extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'subscription_expired', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SameSubscriptionRecurringDataType {
|
||||
@Field() recurring!: string
|
||||
}
|
||||
|
||||
export class SameSubscriptionRecurring extends UserFriendlyError {
|
||||
constructor(args: SameSubscriptionRecurringDataType, message?: string | ((args: SameSubscriptionRecurringDataType) => string)) {
|
||||
super('bad_request', 'same_subscription_recurring', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomerPortalCreateFailed extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'customer_portal_create_failed', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class SubscriptionPlanNotFoundDataType {
|
||||
@Field() plan!: string
|
||||
@Field() recurring!: string
|
||||
}
|
||||
|
||||
export class SubscriptionPlanNotFound extends UserFriendlyError {
|
||||
constructor(args: SubscriptionPlanNotFoundDataType, message?: string | ((args: SubscriptionPlanNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'subscription_plan_not_found', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class CantUpdateOnetimePaymentSubscription extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'cant_update_onetime_payment_subscription', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspaceIdRequiredForTeamSubscription extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'workspace_id_required_for_team_subscription', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspaceIdRequiredToUpdateTeamSubscription extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'workspace_id_required_to_update_team_subscription', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotSessionNotFound extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('resource_not_found', 'copilot_session_not_found', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotSessionDeleted extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'copilot_session_deleted', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class NoCopilotProviderAvailable extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'no_copilot_provider_available', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotFailedToGenerateText extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'copilot_failed_to_generate_text', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotFailedToCreateMessage extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'copilot_failed_to_create_message', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class UnsplashIsNotConfigured extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'unsplash_is_not_configured', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotActionTaken extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'copilot_action_taken', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotMessageNotFoundDataType {
|
||||
@Field() messageId!: string
|
||||
}
|
||||
|
||||
export class CopilotMessageNotFound extends UserFriendlyError {
|
||||
constructor(args: CopilotMessageNotFoundDataType, message?: string | ((args: CopilotMessageNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'copilot_message_not_found', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotPromptNotFoundDataType {
|
||||
@Field() name!: string
|
||||
}
|
||||
|
||||
export class CopilotPromptNotFound extends UserFriendlyError {
|
||||
constructor(args: CopilotPromptNotFoundDataType, message?: string | ((args: CopilotPromptNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'copilot_prompt_not_found', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotPromptInvalid extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'copilot_prompt_invalid', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotProviderSideErrorDataType {
|
||||
@Field() provider!: string
|
||||
@Field() kind!: string
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotProviderSideError extends UserFriendlyError {
|
||||
constructor(args: CopilotProviderSideErrorDataType, message?: string | ((args: CopilotProviderSideErrorDataType) => string)) {
|
||||
super('internal_server_error', 'copilot_provider_side_error', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class BlobQuotaExceeded extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('quota_exceeded', 'blob_quota_exceeded', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class MemberQuotaExceeded extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('quota_exceeded', 'member_quota_exceeded', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotQuotaExceeded extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('quota_exceeded', 'copilot_quota_exceeded', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class RuntimeConfigNotFoundDataType {
|
||||
@Field() key!: string
|
||||
}
|
||||
|
||||
export class RuntimeConfigNotFound extends UserFriendlyError {
|
||||
constructor(args: RuntimeConfigNotFoundDataType, message?: string | ((args: RuntimeConfigNotFoundDataType) => string)) {
|
||||
super('resource_not_found', 'runtime_config_not_found', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class InvalidRuntimeConfigTypeDataType {
|
||||
@Field() key!: string
|
||||
@Field() want!: string
|
||||
@Field() get!: string
|
||||
}
|
||||
|
||||
export class InvalidRuntimeConfigType extends UserFriendlyError {
|
||||
constructor(args: InvalidRuntimeConfigTypeDataType, message?: string | ((args: InvalidRuntimeConfigTypeDataType) => string)) {
|
||||
super('invalid_input', 'invalid_runtime_config_type', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class MailerServiceIsNotConfigured extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('internal_server_error', 'mailer_service_is_not_configured', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CannotDeleteAllAdminAccount extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'cannot_delete_all_admin_account', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CannotDeleteOwnAccount extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'cannot_delete_own_account', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CaptchaVerificationFailed extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'captcha_verification_failed', message);
|
||||
}
|
||||
}
|
||||
export enum ErrorNames {
|
||||
INTERNAL_SERVER_ERROR,
|
||||
TOO_MANY_REQUEST,
|
||||
NOT_FOUND,
|
||||
USER_NOT_FOUND,
|
||||
USER_AVATAR_NOT_FOUND,
|
||||
EMAIL_ALREADY_USED,
|
||||
SAME_EMAIL_PROVIDED,
|
||||
WRONG_SIGN_IN_CREDENTIALS,
|
||||
UNKNOWN_OAUTH_PROVIDER,
|
||||
OAUTH_STATE_EXPIRED,
|
||||
INVALID_OAUTH_CALLBACK_STATE,
|
||||
MISSING_OAUTH_QUERY_PARAMETER,
|
||||
OAUTH_ACCOUNT_ALREADY_CONNECTED,
|
||||
INVALID_EMAIL,
|
||||
INVALID_PASSWORD_LENGTH,
|
||||
PASSWORD_REQUIRED,
|
||||
WRONG_SIGN_IN_METHOD,
|
||||
EARLY_ACCESS_REQUIRED,
|
||||
SIGN_UP_FORBIDDEN,
|
||||
EMAIL_TOKEN_NOT_FOUND,
|
||||
INVALID_EMAIL_TOKEN,
|
||||
LINK_EXPIRED,
|
||||
AUTHENTICATION_REQUIRED,
|
||||
ACTION_FORBIDDEN,
|
||||
ACCESS_DENIED,
|
||||
EMAIL_VERIFICATION_REQUIRED,
|
||||
SPACE_NOT_FOUND,
|
||||
NOT_IN_SPACE,
|
||||
ALREADY_IN_SPACE,
|
||||
SPACE_ACCESS_DENIED,
|
||||
SPACE_OWNER_NOT_FOUND,
|
||||
CANT_CHANGE_SPACE_OWNER,
|
||||
DOC_NOT_FOUND,
|
||||
DOC_ACCESS_DENIED,
|
||||
VERSION_REJECTED,
|
||||
INVALID_HISTORY_TIMESTAMP,
|
||||
DOC_HISTORY_NOT_FOUND,
|
||||
BLOB_NOT_FOUND,
|
||||
EXPECT_TO_PUBLISH_PAGE,
|
||||
EXPECT_TO_REVOKE_PUBLIC_PAGE,
|
||||
PAGE_IS_NOT_PUBLIC,
|
||||
FAILED_TO_SAVE_UPDATES,
|
||||
FAILED_TO_UPSERT_SNAPSHOT,
|
||||
UNSUPPORTED_SUBSCRIPTION_PLAN,
|
||||
FAILED_TO_CHECKOUT,
|
||||
INVALID_CHECKOUT_PARAMETERS,
|
||||
SUBSCRIPTION_ALREADY_EXISTS,
|
||||
INVALID_SUBSCRIPTION_PARAMETERS,
|
||||
SUBSCRIPTION_NOT_EXISTS,
|
||||
SUBSCRIPTION_HAS_BEEN_CANCELED,
|
||||
SUBSCRIPTION_HAS_NOT_BEEN_CANCELED,
|
||||
SUBSCRIPTION_EXPIRED,
|
||||
SAME_SUBSCRIPTION_RECURRING,
|
||||
CUSTOMER_PORTAL_CREATE_FAILED,
|
||||
SUBSCRIPTION_PLAN_NOT_FOUND,
|
||||
CANT_UPDATE_ONETIME_PAYMENT_SUBSCRIPTION,
|
||||
WORKSPACE_ID_REQUIRED_FOR_TEAM_SUBSCRIPTION,
|
||||
WORKSPACE_ID_REQUIRED_TO_UPDATE_TEAM_SUBSCRIPTION,
|
||||
COPILOT_SESSION_NOT_FOUND,
|
||||
COPILOT_SESSION_DELETED,
|
||||
NO_COPILOT_PROVIDER_AVAILABLE,
|
||||
COPILOT_FAILED_TO_GENERATE_TEXT,
|
||||
COPILOT_FAILED_TO_CREATE_MESSAGE,
|
||||
UNSPLASH_IS_NOT_CONFIGURED,
|
||||
COPILOT_ACTION_TAKEN,
|
||||
COPILOT_MESSAGE_NOT_FOUND,
|
||||
COPILOT_PROMPT_NOT_FOUND,
|
||||
COPILOT_PROMPT_INVALID,
|
||||
COPILOT_PROVIDER_SIDE_ERROR,
|
||||
BLOB_QUOTA_EXCEEDED,
|
||||
MEMBER_QUOTA_EXCEEDED,
|
||||
COPILOT_QUOTA_EXCEEDED,
|
||||
RUNTIME_CONFIG_NOT_FOUND,
|
||||
INVALID_RUNTIME_CONFIG_TYPE,
|
||||
MAILER_SERVICE_IS_NOT_CONFIGURED,
|
||||
CANNOT_DELETE_ALL_ADMIN_ACCOUNT,
|
||||
CANNOT_DELETE_OWN_ACCOUNT,
|
||||
CAPTCHA_VERIFICATION_FAILED
|
||||
}
|
||||
registerEnumType(ErrorNames, {
|
||||
name: 'ErrorNames'
|
||||
})
|
||||
|
||||
export const ErrorDataUnionType = createUnionType({
|
||||
name: 'ErrorDataUnion',
|
||||
types: () =>
|
||||
[WrongSignInCredentialsDataType, UnknownOauthProviderDataType, MissingOauthQueryParameterDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, SpaceNotFoundDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, DocNotFoundDataType, DocAccessDeniedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderSideErrorDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType] as const,
|
||||
});
|
||||
42
packages/backend/server/src/base/error/index.ts
Normal file
42
packages/backend/server/src/base/error/index.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { Logger, Module, OnModuleInit } from '@nestjs/common';
|
||||
import { Args, Query, Resolver } from '@nestjs/graphql';
|
||||
|
||||
import { Config } from '../config/provider';
|
||||
import { generateUserFriendlyErrors } from './def';
|
||||
import { ActionForbidden, ErrorDataUnionType, ErrorNames } from './errors.gen';
|
||||
|
||||
@Resolver(() => ErrorDataUnionType)
|
||||
class ErrorResolver {
|
||||
// only exists for type registering
|
||||
@Query(() => ErrorDataUnionType)
|
||||
error(@Args({ name: 'name', type: () => ErrorNames }) _name: ErrorNames) {
|
||||
throw new ActionForbidden();
|
||||
}
|
||||
}
|
||||
|
||||
@Module({
|
||||
providers: [ErrorResolver],
|
||||
})
|
||||
export class ErrorModule implements OnModuleInit {
|
||||
logger = new Logger('ErrorModule');
|
||||
constructor(private readonly config: Config) {}
|
||||
onModuleInit() {
|
||||
if (!this.config.node.dev) {
|
||||
return;
|
||||
}
|
||||
this.logger.log('Generating UserFriendlyError classes');
|
||||
const def = generateUserFriendlyErrors();
|
||||
|
||||
writeFileSync(
|
||||
join(fileURLToPath(import.meta.url), '../errors.gen.ts'),
|
||||
def
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { UserFriendlyError } from './def';
|
||||
export * from './errors.gen';
|
||||
Reference in New Issue
Block a user