feat(i18n): introduce server error i18n (#9953)

close AF-2054
This commit is contained in:
forehalo
2025-02-05 12:30:18 +00:00
parent 4a943d854e
commit 4ed03c9f0e
12 changed files with 709 additions and 110 deletions

View File

@@ -15,10 +15,11 @@ export function isNetworkError(error: Error): error is NetworkError {
}
export class BackendError extends Error {
constructor(
public readonly originError: UserFriendlyError,
public readonly status?: number
) {
get status() {
return this.originError.status;
}
constructor(public readonly originError: UserFriendlyError) {
super(`Server error: ${originError.message}`);
this.stack = originError.stack;
}

View File

@@ -78,10 +78,7 @@ export class FetchService extends Service {
// ignore
}
}
throw new BackendError(
UserFriendlyError.fromAnyError(reason),
res.status
);
throw new BackendError(UserFriendlyError.fromAnyError(reason));
}
return res;
};

View File

@@ -1,8 +1,10 @@
import {
gqlFetcherFactory,
GraphQLError,
type GraphQLQuery,
type QueryOptions,
type QueryResponse,
UserFriendlyError,
} from '@affine/graphql';
import { fromPromise, Service } from '@toeverything/infra';
import type { Observable } from 'rxjs';
@@ -37,12 +39,21 @@ export class GraphQLService extends Service {
): Promise<QueryResponse<Query>> => {
try {
return await this.rawGql(options);
} catch (err) {
if (err instanceof BackendError && err.status === 403) {
} catch (anyError) {
let error = anyError;
// NOTE(@forehalo):
// GraphQL error is not present by non-200 status code, but by responding `errors` fields in the body
// So it will never be `BackendError` originally.
if (anyError instanceof GraphQLError) {
error = new BackendError(UserFriendlyError.fromAnyError(anyError));
}
if (error instanceof BackendError && error.status === 403) {
this.framework.get(AuthService).session.revalidate();
}
throw err;
throw error;
}
};
}