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