Skip to content

Commit 4304fd5

Browse files
authored
fix: catch set object storage policy error (#365)
* CHORE * chore: update env * chore: clean redundant codes and add more logs
1 parent fe153b0 commit 4304fd5

File tree

5 files changed

+50
-60
lines changed

5 files changed

+50
-60
lines changed

lib/mongo/index.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { isProd } from '../constants';
22
import { getLogger, infra } from '../logger';
33
import { env } from '../env';
44

5-
const logger = getLogger(infra.mongo);
65
import type { Model, Schema } from 'mongoose';
76
import { Mongoose } from 'mongoose';
87

@@ -35,10 +34,11 @@ const addCommonMiddleware = (schema: Schema) => {
3534
});
3635

3736
schema.post(op, function (this: any, result: any, next: () => void) {
37+
const logger = getLogger(infra.mongo);
3838
if (this._startTime) {
3939
const duration = Date.now() - this._startTime;
4040
if (duration > 1000) {
41-
logger.warn('Slow operation ${duration}ms on ${this.collection?.name}');
41+
logger.warn(`Slow operation ${duration}ms on ${this.collection?.name}`);
4242
}
4343
}
4444
next();
@@ -50,7 +50,10 @@ const addCommonMiddleware = (schema: Schema) => {
5050

5151
export const getMongoModel = <T extends Schema>(name: string, schema: T): Model<any> => {
5252
if (connectionMongo.models[name]) return connectionMongo.model(name) as Model<any>;
53-
if (!isProd) logger.info('Load model: ${name}');
53+
if (!isProd) {
54+
const logger = getLogger(infra.mongo);
55+
logger.info(`Load model: ${name}`);
56+
}
5457
addCommonMiddleware(schema);
5558

5659
const model = connectionMongo.model(name, schema);
@@ -65,23 +68,26 @@ const syncMongoIndex = async (model: Model<any>) => {
6568
try {
6669
model.syncIndexes({ background: true });
6770
} catch (error: any) {
68-
logger.error('Create index error', { error });
71+
const logger = getLogger(infra.mongo);
72+
logger.error(`Create index error: ${JSON.stringify(error, null, 2)}`, { error });
6973
}
7074
}
7175
};
7276

7377
export const ReadPreference = connectionMongo.mongo.ReadPreference;
7478

7579
export async function connectMongo(db: Mongoose, url: string): Promise<Mongoose> {
80+
const logger = getLogger(infra.mongo);
7681
if (db.connection.readyState !== 0) {
7782
return db;
7883
}
7984

8085
if (!url || typeof url !== 'string') {
86+
logger.error(`Invalid MongoDB connection URL: ${url}`);
8187
throw new Error(`Invalid MongoDB connection URL: ${url}`);
8288
}
8389

84-
console.log(`connecting to ${isProd ? 'MongoDB' : url}`);
90+
logger.info(`try to connect to ${isProd ? 'MongoDB' : url}`);
8591

8692
try {
8793
db.connection.removeAllListeners('error');
@@ -90,15 +96,15 @@ export async function connectMongo(db: Mongoose, url: string): Promise<Mongoose>
9096

9197
// Log errors but don't reconnect here to avoid duplicate reconnection
9298
db.connection.on('error', (error: any) => {
93-
console.error('mongo error', error);
99+
logger.error(`Mongo error: ${JSON.stringify(error, null, 2)}`, { error });
94100
});
95101

96102
db.connection.on('connected', () => {
97-
console.log('mongo connected');
103+
logger.info('Mongo connected');
98104
});
99105
// Handle reconnection on disconnect
100106
db.connection.on('disconnected', async () => {
101-
console.error('mongo disconnected');
107+
logger.warn('Mongo disconnected');
102108
});
103109

104110
await db.connect(url, {
@@ -117,7 +123,7 @@ export async function connectMongo(db: Mongoose, url: string): Promise<Mongoose>
117123
});
118124
return db;
119125
} catch (error) {
120-
logger.error('Mongo connect error', { error });
126+
logger.error(`Mongo connect error: ${JSON.stringify(error, null, 2)}`, { error });
121127
await db.disconnect();
122128
await delay(1000);
123129
return connectMongo(db, url);

lib/redis/index.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
import { getLogger, infra } from '@/logger';
22
import { env } from '@/env';
33

4-
const logger = getLogger(infra.redis);
54
import Redis from 'ioredis';
65

76
// Base Redis options for connection reliability
87
const REDIS_BASE_OPTION = {
98
// Retry strategy: exponential backoff with unlimited retries for stability
109
retryStrategy: (times: number) => {
10+
const logger = getLogger(infra.redis);
1111
// Never give up retrying to ensure worker keeps running
1212
const delay = Math.min(times * 50, 2000); // Max 2s between retries
1313
if (times > 10) {
14-
logger.error('[Redis connection failed] attempt ${times}, will keep retrying...');
14+
logger.error(`[Redis connection failed] attempt ${times}, will keep retrying...`);
1515
} else {
16-
logger.warn('Redis reconnecting... attempt ${times}, delay ${delay}ms');
16+
logger.warn(`Redis reconnecting... attempt ${times}, delay ${delay}ms`);
1717
}
1818
return delay; // Always return a delay to keep retrying
1919
},
2020
// Reconnect on specific errors (Redis master-slave switch, network issues)
21-
reconnectOnError: (err: any) => {
21+
reconnectOnError: (error: any) => {
22+
const logger = getLogger(infra.redis);
2223
const reconnectErrors = ['READONLY', 'ECONNREFUSED', 'ETIMEDOUT', 'ECONNRESET'];
23-
const message = typeof err?.message === 'string' ? err.message : String(err ?? '');
24+
const message = typeof error?.message === 'string' ? error.message : String(error ?? '');
2425

2526
const shouldReconnect = reconnectErrors.some((errType) => message.includes(errType));
2627
if (shouldReconnect) {
27-
logger.warn('Redis reconnecting due to error: ${message}');
28+
logger.warn(`Redis reconnecting due to error: ${JSON.stringify(error, null, 2)}`, { error });
2829
}
2930
return shouldReconnect;
3031
},
@@ -36,6 +37,7 @@ const REDIS_BASE_OPTION = {
3637

3738
export const FASTGPT_REDIS_PREFIX = 'fastgpt:';
3839
export const getGlobalRedisConnection = () => {
40+
const logger = getLogger(infra.redis);
3941
if (global.redisClient) return global.redisClient;
4042

4143
global.redisClient = new Redis(env.REDIS_URL, {
@@ -47,7 +49,7 @@ export const getGlobalRedisConnection = () => {
4749
logger.info('Redis connected');
4850
});
4951
global.redisClient.on('error', (error) => {
50-
logger.error('Redis connection error', { error });
52+
logger.error(`Redis connection error: ${JSON.stringify(error, null, 2)}`, { error });
5153
});
5254

5355
return global.redisClient;

lib/s3/index.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import {
1111
} from '@fastgpt-sdk/storage';
1212
import { getLogger, infra } from '@/logger';
1313

14-
const logger = getLogger(infra.storage);
15-
1614
type StorageConfigWithoutBucket = Omit<IStorageOptions, 'bucket'>;
1715

1816
const getConfig = () => {
@@ -90,11 +88,16 @@ const createS3Service = async (bucket: string, isPublic: boolean) => {
9088
}
9189
};
9290

93-
await client.ensureBucket();
94-
if (isPublic) await ensurePublicPolicy(client);
95-
96-
await externalClient?.ensureBucket();
97-
if (isPublic && externalClient) await ensurePublicPolicy(externalClient);
91+
try {
92+
await client.ensureBucket();
93+
if (isPublic) await ensurePublicPolicy(client);
94+
95+
await externalClient?.ensureBucket();
96+
if (isPublic && externalClient) await ensurePublicPolicy(externalClient);
97+
} catch (error) {
98+
const logger = getLogger(infra.storage);
99+
logger.warn(`Ensure bucket warn: ${JSON.stringify(error, null, 2)}`, { error });
100+
}
98101

99102
return new S3Service(client, externalClient);
100103
};
@@ -122,9 +125,9 @@ export const initS3Service = async () => {
122125
logger.debug('Initializing private S3 service...');
123126
s3ServiceInstances.privateS3Server = await createS3Service(privateBucket, false);
124127
}
125-
} catch (e) {
126-
logger.error('Failed to initialize S3 service:', { error: e });
127-
throw new Error('Failed to initialize S3 service');
128+
} catch (error) {
129+
logger.error(`Failed to initialize S3 service: ${JSON.stringify(error, null, 2)}`, { error });
130+
throw error;
128131
}
129132
};
130133

runtime/.env.template

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ DISABLE_CACHE=true
1111
CHECK_INTERNAL_IP=true
1212
MODEL_PROVIDER_PRIORITY=
1313
MAX_FILE_SIZE=213483520
14+
FASTGPT_BASE_URL=http://localhost:3000
1415

1516
# ================ 代理 =====================
1617
HTTP_PROXY=
@@ -42,6 +43,3 @@ STORAGE_S3_ENDPOINT=http://localhost:9000
4243
STORAGE_S3_FORCE_PATH_STYLE=true
4344
STORAGE_S3_MAX_RETRIES=3
4445
STORAGE_PUBLIC_ACCESS_EXTRA_SUB_PATH=
45-
46-
# reverse invoking
47-
FASTGPT_BASE_URL=http://localhost:3000

runtime/app.ts

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { cors } from 'hono/cors';
22
import models from '@model/route';
33
import workflow from '@workflow/route';
44
import tool from '@tool/route';
5-
import { isProd } from '@/constants';
65
import { createResponseSchema, R, createOpenAPIHono } from '@/utils/http';
7-
import { serveStatic } from '@hono/node-server/serve-static';
8-
import { basePath } from '@tool/constants';
9-
import path from 'node:path';
106
import { bearerAuth } from 'hono/bearer-auth';
117
import { env } from '@/env';
128
import { HTTPException } from 'hono/http-exception';
@@ -27,13 +23,6 @@ app.use(
2723
credentials: true
2824
})
2925
);
30-
app.use(
31-
'/public/*',
32-
serveStatic({
33-
root: isProd ? 'public' : path.join(basePath, 'dist', 'public'),
34-
rewriteRequestPath: (path) => path.replace(/^\/public/, '')
35-
})
36-
);
3726
app.use('/api/*', bearerAuth({ token: env.AUTH_TOKEN }));
3827
app.use('*', requestId());
3928
app.use('*', logger);
@@ -98,28 +87,20 @@ app.route('/api', workflow);
9887
app.route('/api', tool);
9988
// #endregion
10089

101-
app.onError((err, c) => {
102-
if (err instanceof HTTPException) {
103-
const message = err.status === 401 ? 'Unauthorized' : err.message;
104-
c.status(err.status);
105-
return R.fail(c, {
106-
code: err.status,
107-
msg: message
108-
});
109-
}
90+
app.onError((error, c) => {
91+
if (error instanceof HTTPException) {
92+
const message = error.status === 401 ? 'Unauthorized' : error.message;
11093

111-
c.get('logger').error('Internal Server Error', {
112-
error: {
113-
message: err.message,
114-
stack: err.stack,
115-
name: err.name
116-
}
117-
});
94+
console.warn('HTTP Exception: ', error);
95+
c.get('logger').warn(`HTTP Exception: ${JSON.stringify(error, null, 2)}`, { error });
96+
97+
c.status(error.status);
98+
return R.fail(c, { code: error.status, msg: message });
99+
}
118100

119-
return R.fail(c, {
120-
code: 500,
121-
msg: err.message || 'Internal Server Error'
122-
});
101+
console.error('Internal Server Error: ', error);
102+
c.get('logger').error(`Internal Server Error: ${JSON.stringify(error, null, 2)}`, { error });
103+
return R.fail(c, { code: 500, msg: error.message || 'Internal Server Error' });
123104
});
124105

125106
app.notFound((c) => {

0 commit comments

Comments
 (0)