Merge branch 'main' into next

This commit is contained in:
nocobase[bot]
2026-06-09 14:17:38 +00:00
3 changed files with 72 additions and 2 deletions
+1
View File
@@ -84,6 +84,7 @@ export class BaseAuth extends Auth {
this.ctx.throw(401, {
message: this.ctx.t('Unauthenticated. Please sign in to continue.', { ns: localeNamespace }),
code: AuthErrorCode.EMPTY_TOKEN,
logLevel: 'trace',
});
}
@@ -9,7 +9,9 @@
import { Database } from '@nocobase/database';
import { MockServer, createMockServer } from '@nocobase/test';
import { vi } from 'vitest';
import Plugin from '..';
import { ErrorHandler } from '../error-handler';
describe('middleware', () => {
let app: MockServer;
@@ -70,4 +72,60 @@ describe('middleware', () => {
errors: ['custom error'],
});
});
it('should respect error log level', async () => {
const errorHandler = new ErrorHandler();
const trace = vi.fn();
const error = vi.fn();
const err = Object.assign(new Error('Unauthenticated. Please sign in to continue.'), {
code: 'EMPTY_TOKEN',
logLevel: 'trace',
status: 401,
});
const ctx = { log: { trace, error } };
await errorHandler.middleware()(ctx, async () => {
throw err;
});
expect(ctx).toMatchObject({
status: 401,
body: {
errors: [
{
code: 'EMPTY_TOKEN',
message: 'Unauthenticated. Please sign in to continue.',
},
],
},
});
expect(trace).toHaveBeenCalledWith(err.message, {
method: 'error-handler',
err: err.stack,
cause: err.cause,
});
expect(error).not.toHaveBeenCalled();
});
it('should keep errors without log level as error logs', async () => {
const errorHandler = new ErrorHandler();
const trace = vi.fn();
const error = vi.fn();
const err = Object.assign(new Error('Your session has expired. Please sign in again.'), {
code: 'INVALID_TOKEN',
status: 401,
});
const ctx = { log: { trace, error } };
await errorHandler.middleware()(ctx, async () => {
throw err;
});
expect(error).toHaveBeenCalledWith(err.message, {
method: 'error-handler',
err: err.stack,
cause: err.cause,
});
expect(trace).not.toHaveBeenCalled();
});
});
@@ -55,14 +55,25 @@ export class ErrorHandler {
try {
await next();
} catch (err) {
ctx.log.error(err.message, { method: 'error-handler', err: err.stack, cause: err.cause });
if (err.statusCode) {
ctx.status = err.statusCode;
}
self.renderError(err, ctx);
const logMethod = getLogMethod(err);
ctx.log[logMethod](err.message, { method: 'error-handler', err: err.stack, cause: err.cause });
}
};
}
}
const logMethods = ['trace', 'debug', 'info', 'warn', 'error'];
function getLogMethod(err) {
if (logMethods.includes(err?.logLevel)) {
return err.logLevel;
}
return 'error';
}