mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 14:39:25 +08:00
feat: provide more user-friendly application-level error messages (#5220)
* fix: display app maintaining message * fix: app error
This commit is contained in:
parent
efac16c6a9
commit
6d2f17a7c3
@ -92,7 +92,7 @@ export class APIClient extends APIClientSDK {
|
||||
return response;
|
||||
},
|
||||
(error) => {
|
||||
const errs = error?.response?.data?.errors || [{ message: 'Server error' }];
|
||||
const errs = this.toErrMessages(error);
|
||||
// Hard code here temporarily
|
||||
// TODO(yangqia): improve error code and message
|
||||
if (errs.find((error: { code?: string }) => error.code === 'ROLE_NOT_FOUND_ERR')) {
|
||||
@ -103,6 +103,17 @@ export class APIClient extends APIClientSDK {
|
||||
);
|
||||
}
|
||||
|
||||
toErrMessages(error) {
|
||||
if (typeof error?.response?.data === 'string') {
|
||||
return [{ message: error?.response?.data }];
|
||||
}
|
||||
return (
|
||||
error?.response?.data?.errors ||
|
||||
error?.response?.data?.messages ||
|
||||
error?.response?.error || [{ message: error.message || 'Server error' }]
|
||||
);
|
||||
}
|
||||
|
||||
useNotificationMiddleware() {
|
||||
this.axios.interceptors.response.use(
|
||||
(response) => {
|
||||
@ -143,7 +154,7 @@ export class APIClient extends APIClientSDK {
|
||||
} else if (this.app.error) {
|
||||
this.app.error = null;
|
||||
}
|
||||
let errs = error?.response?.data?.errors || error?.response?.data?.messages || [{ message: 'Server error' }];
|
||||
let errs = this.toErrMessages(error);
|
||||
errs = errs.filter((error) => {
|
||||
const lastTime = errorCache.get(error.message);
|
||||
if (lastTime && new Date().getTime() - lastTime < 500) {
|
||||
|
@ -34,17 +34,17 @@ import { compose, normalizeContainer } from './utils';
|
||||
import { defineGlobalDeps } from './utils/globalDeps';
|
||||
import { getRequireJs } from './utils/requirejs';
|
||||
|
||||
import { CollectionFieldInterfaceComponentOption } from '../data-source/collection-field-interface/CollectionFieldInterface';
|
||||
import { CollectionField } from '../data-source/collection-field/CollectionField';
|
||||
import { DataSourceApplicationProvider } from '../data-source/components/DataSourceApplicationProvider';
|
||||
import { DataBlockProvider } from '../data-source/data-block/DataBlockProvider';
|
||||
import { DataSourceManager, type DataSourceManagerOptions } from '../data-source/data-source/DataSourceManager';
|
||||
import { CollectionFieldInterfaceComponentOption } from '../data-source/collection-field-interface/CollectionFieldInterface';
|
||||
|
||||
import type { CollectionFieldInterfaceFactory } from '../data-source';
|
||||
import { OpenModeProvider } from '../modules/popup/OpenModeProvider';
|
||||
import { AppSchemaComponentProvider } from './AppSchemaComponentProvider';
|
||||
import type { Plugin } from './Plugin';
|
||||
import type { RequireJS } from './utils/requirejs';
|
||||
import type { CollectionFieldInterfaceFactory } from '../data-source';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -282,10 +282,21 @@ export class Application {
|
||||
});
|
||||
}
|
||||
loadFailed = true;
|
||||
const others = error?.response?.data?.error || error?.response?.data?.errors?.[0] || { message: error?.message };
|
||||
const toError = (error) => {
|
||||
if (typeof error?.response?.data === 'string') {
|
||||
return { message: error?.response?.data };
|
||||
}
|
||||
if (error?.response?.data?.error) {
|
||||
return error?.response?.data?.error;
|
||||
}
|
||||
if (error?.response?.data?.errors?.[0]) {
|
||||
return error?.response?.data?.errors?.[0];
|
||||
}
|
||||
return { message: error?.message };
|
||||
};
|
||||
this.error = {
|
||||
code: 'LOAD_ERROR',
|
||||
...others,
|
||||
...toError(error),
|
||||
};
|
||||
console.error(error, this.error);
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ const getProps = (app: Application) => {
|
||||
};
|
||||
}
|
||||
|
||||
if (app.error.code === 'APP_ERROR' || app.error.code === 'LOAD_ERROR') {
|
||||
if (['ENOENT', 'APP_ERROR', 'LOAD_ERROR'].includes(app.error.code)) {
|
||||
return {
|
||||
status: 'error',
|
||||
title: 'App error',
|
||||
@ -205,7 +205,11 @@ const getProps = (app: Application) => {
|
||||
return { ...props, ...commands[app.error?.command?.name] };
|
||||
}
|
||||
|
||||
return {};
|
||||
return {
|
||||
status: 'warning',
|
||||
title: 'App warning',
|
||||
subTitle: app.error?.message,
|
||||
};
|
||||
};
|
||||
|
||||
const AppMaintaining: FC<{ app: Application; error: Error }> = observer(
|
||||
|
@ -9,11 +9,10 @@
|
||||
|
||||
import { uid } from '@nocobase/utils';
|
||||
import fs from 'fs';
|
||||
import fse from 'fs-extra';
|
||||
import path from 'path';
|
||||
import Application from '../../application';
|
||||
import { getExposeUrl } from '../clientStaticUtils';
|
||||
import PluginManager from '../plugin-manager';
|
||||
//@ts-ignore
|
||||
|
||||
export default {
|
||||
name: 'pm',
|
||||
@ -135,21 +134,19 @@ export default {
|
||||
enabled: true,
|
||||
},
|
||||
});
|
||||
ctx.body = items
|
||||
.map((item) => {
|
||||
try {
|
||||
return {
|
||||
...item.toJSON(),
|
||||
url: `${process.env.APP_SERVER_BASE_URL}${getExposeUrl(
|
||||
item.packageName,
|
||||
PLUGIN_CLIENT_ENTRY_FILE,
|
||||
)}?version=${item.version}`,
|
||||
};
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
const arr = [];
|
||||
for (const item of items) {
|
||||
const pkgPath = path.resolve(process.env.NODE_MODULES_PATH, item.packageName);
|
||||
const r = await fse.exists(pkgPath);
|
||||
if (r) {
|
||||
const url = `${process.env.APP_SERVER_BASE_URL}${process.env.PLUGIN_STATICS_PATH}${item.packageName}/${PLUGIN_CLIENT_ENTRY_FILE}?version=${item.version}`;
|
||||
arr.push({
|
||||
...item.toJSON(),
|
||||
url,
|
||||
});
|
||||
}
|
||||
}
|
||||
ctx.body = arr;
|
||||
await next();
|
||||
},
|
||||
async get(ctx, next) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user