@hiliosai/sdk 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +14 -4
- package/dist/index.js +251 -90
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ interface AppMeta {
|
|
|
46
46
|
requestId?: string;
|
|
47
47
|
userAgent?: string;
|
|
48
48
|
clientIP?: string;
|
|
49
|
+
startTime?: Date;
|
|
49
50
|
[key: string]: unknown;
|
|
50
51
|
}
|
|
51
52
|
interface PermissionHelpers {
|
|
@@ -899,6 +900,15 @@ type Env = typeof env;
|
|
|
899
900
|
*/
|
|
900
901
|
declare function DatasourceMixin(datasourceConstructors?: DatasourceConstructorRegistry): Partial<ServiceSchema$1>;
|
|
901
902
|
|
|
903
|
+
/**
|
|
904
|
+
* Determines the appropriate log level based on error code/status
|
|
905
|
+
*/
|
|
906
|
+
declare function getErrorLogLevel(code?: string | number): 'fatal' | 'error' | 'warn' | 'info';
|
|
907
|
+
/**
|
|
908
|
+
* Sanitizes error data to remove sensitive information
|
|
909
|
+
*/
|
|
910
|
+
declare function sanitizeErrorData(data: unknown): unknown;
|
|
911
|
+
|
|
902
912
|
declare function omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K>;
|
|
903
913
|
|
|
904
914
|
declare class PermissionError extends Error {
|
|
@@ -948,10 +958,10 @@ interface GatewayError extends Error {
|
|
|
948
958
|
* }
|
|
949
959
|
* }
|
|
950
960
|
*/
|
|
951
|
-
declare
|
|
961
|
+
declare function gatewayErrorHandler(this: Service, req: IncomingMessage & {
|
|
952
962
|
$ctx?: AppContext;
|
|
953
963
|
originalUrl?: string;
|
|
954
|
-
}, res: ServerResponse, error: GatewayError)
|
|
964
|
+
}, res: ServerResponse, error: GatewayError): void;
|
|
955
965
|
|
|
956
966
|
declare class DBError extends Errors.MoleculerError {
|
|
957
967
|
constructor(message: string, code: number, type?: string, data?: unknown);
|
|
@@ -974,6 +984,6 @@ declare class DBTimeoutError extends Errors.MoleculerError {
|
|
|
974
984
|
declare class DBTransactionError extends Errors.MoleculerError {
|
|
975
985
|
constructor(message: string, data?: unknown);
|
|
976
986
|
}
|
|
977
|
-
declare
|
|
987
|
+
declare function prismaErrorHandler(this: ServiceBroker, err: Error, info: BrokerErrorHandlerInfoAction): undefined;
|
|
978
988
|
|
|
979
|
-
export { AbstractDatasource, type ActionHandler, type ActionWithPermissions, type AppContext, type AppMeta, type AuditTrailExtension, AuthenticationError, type BaseDatasource, type BaseSpec, CHANNELS, type CarouselItem, type ChannelSendOptions, ContextHelpersMiddleware, CreateHealthCheckMiddleware, DBConnectionError, DBConstraintError, DBError, DBNotFoundError, DBTimeoutError, DBTransactionError, DBValidationError, DEFAULT_DATASOURCE_CACHE_TTL, type DatasourceConstructorRegistry, type DatasourceContext, type DatasourceInstanceRegistry, type DatasourceInstanceTypes, DatasourceMixin, type Env, type GatewayError, HEALTH_CHECK_DEFAULTS, INTEGRATION_CHANNELS, IntegrationCapability, type IntegrationChannelName, type IntegrationConfig, type IntegrationMessageFailedPayload, type IntegrationMessageReceivedPayload, type IntegrationMessageSentPayload, IntegrationPlatform, type IntegrationRegisteredPayload, type IntegrationServiceConfig, type IntegrationServiceSchema, IntegrationStatus, type IntegrationUnregisteredPayload, MemoizeMixin, type MemoizeMixinOptions, type Message, type MessageAttachment, type MessageButton, type MessageContent, MessageContentType, type MessageDirection, type MessageParticipant, type MessageStatus, type MessageType, NAMESPACE, PERMISSIONS, type Permission, PermissionError, type PermissionHelpers, PermissionsMiddleware, type PlatformMessage, type PrismaClientLike, type PrismaClientWithTenant, PrismaDatasource, PrismaPgDatasource, REDIS_URL, ROLE_PERMISSIONS, type SendResult, type SendToChannelMethod, type ServiceActionsSchema, type ServiceConfig, type ServiceSchema, type ServiceWithDatasources, type SoftDeleteExtension, type Tenant, TenantError, type TenantExtension, type User, UserRole, type WebhookEvent, createDatasourceMiddleware, createTenantExtension, defineIntegration, defineService, gatewayErrorHandler, isDev, isProd, isTest, configs as moleculer, nodeEnv, omit, prismaErrorHandler, retryExtension, softDeleteExtension };
|
|
989
|
+
export { AbstractDatasource, type ActionHandler, type ActionWithPermissions, type AppContext, type AppMeta, type AuditTrailExtension, AuthenticationError, type BaseDatasource, type BaseSpec, CHANNELS, type CarouselItem, type ChannelSendOptions, ContextHelpersMiddleware, CreateHealthCheckMiddleware, DBConnectionError, DBConstraintError, DBError, DBNotFoundError, DBTimeoutError, DBTransactionError, DBValidationError, DEFAULT_DATASOURCE_CACHE_TTL, type DatasourceConstructorRegistry, type DatasourceContext, type DatasourceInstanceRegistry, type DatasourceInstanceTypes, DatasourceMixin, type Env, type GatewayError, HEALTH_CHECK_DEFAULTS, INTEGRATION_CHANNELS, IntegrationCapability, type IntegrationChannelName, type IntegrationConfig, type IntegrationMessageFailedPayload, type IntegrationMessageReceivedPayload, type IntegrationMessageSentPayload, IntegrationPlatform, type IntegrationRegisteredPayload, type IntegrationServiceConfig, type IntegrationServiceSchema, IntegrationStatus, type IntegrationUnregisteredPayload, MemoizeMixin, type MemoizeMixinOptions, type Message, type MessageAttachment, type MessageButton, type MessageContent, MessageContentType, type MessageDirection, type MessageParticipant, type MessageStatus, type MessageType, NAMESPACE, PERMISSIONS, type Permission, PermissionError, type PermissionHelpers, PermissionsMiddleware, type PlatformMessage, type PrismaClientLike, type PrismaClientWithTenant, PrismaDatasource, PrismaPgDatasource, REDIS_URL, ROLE_PERMISSIONS, type SendResult, type SendToChannelMethod, type ServiceActionsSchema, type ServiceConfig, type ServiceSchema, type ServiceWithDatasources, type SoftDeleteExtension, type Tenant, TenantError, type TenantExtension, type User, UserRole, type WebhookEvent, createDatasourceMiddleware, createTenantExtension, defineIntegration, defineService, gatewayErrorHandler, getErrorLogLevel, isDev, isProd, isTest, configs as moleculer, nodeEnv, omit, prismaErrorHandler, retryExtension, sanitizeErrorData, softDeleteExtension };
|
package/dist/index.js
CHANGED
|
@@ -300,9 +300,9 @@ var TenantError = class _TenantError extends Error {
|
|
|
300
300
|
};
|
|
301
301
|
|
|
302
302
|
// src/errors/gateway.error.ts
|
|
303
|
-
|
|
303
|
+
function gatewayErrorHandler(req, res, error) {
|
|
304
304
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
305
|
-
const statusCode = error.code
|
|
305
|
+
const statusCode = typeof error.code === "number" ? error.code : typeof error.statusCode === "number" ? error.statusCode : 500;
|
|
306
306
|
res.writeHead(statusCode);
|
|
307
307
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
308
308
|
const requestId = req.$ctx?.id ?? req.$ctx?.requestID;
|
|
@@ -349,8 +349,21 @@ var gatewayErrorHandler = (req, res, error) => {
|
|
|
349
349
|
...docLinks[errorCode] && { help: docLinks[errorCode] }
|
|
350
350
|
}
|
|
351
351
|
};
|
|
352
|
+
const logLevel = statusCode >= 500 ? "error" : statusCode >= 400 ? "warn" : "info";
|
|
353
|
+
this.logger[logLevel]("API Gateway Error", {
|
|
354
|
+
code: errorCode,
|
|
355
|
+
statusCode,
|
|
356
|
+
message: error.message,
|
|
357
|
+
requestId,
|
|
358
|
+
path,
|
|
359
|
+
method: req.method,
|
|
360
|
+
timestamp,
|
|
361
|
+
details: details.length > 0 ? details : void 0,
|
|
362
|
+
stack: statusCode >= 500 ? error.stack : void 0,
|
|
363
|
+
data: error.data
|
|
364
|
+
});
|
|
352
365
|
res.end(JSON.stringify(response));
|
|
353
|
-
}
|
|
366
|
+
}
|
|
354
367
|
var DBError = class extends Errors.MoleculerError {
|
|
355
368
|
constructor(message, code, type = "DB_ERROR", data) {
|
|
356
369
|
super(message, code, type, data);
|
|
@@ -386,33 +399,46 @@ var DBTransactionError = class extends Errors.MoleculerError {
|
|
|
386
399
|
super(message, 500, "TRANSACTION_ERROR", data);
|
|
387
400
|
}
|
|
388
401
|
};
|
|
402
|
+
function logPrismaError(ctx, errorType, errorCode, message, meta) {
|
|
403
|
+
const logLevel = typeof errorCode === "number" && errorCode >= 500 ? "error" : "warn";
|
|
404
|
+
this.logger[logLevel]("Database Error", {
|
|
405
|
+
type: errorType,
|
|
406
|
+
code: errorCode,
|
|
407
|
+
message,
|
|
408
|
+
requestId: ctx.id,
|
|
409
|
+
service: this.name,
|
|
410
|
+
action: ctx.action?.name,
|
|
411
|
+
meta,
|
|
412
|
+
caller: ctx.caller
|
|
413
|
+
});
|
|
414
|
+
}
|
|
389
415
|
var prismaErrorHandlers = {
|
|
390
|
-
P2002
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
);
|
|
416
|
+
P2002(err, ctx) {
|
|
417
|
+
const errorType = "UNIQUE_VIOLATION";
|
|
418
|
+
const message = "Unique constraint violation";
|
|
419
|
+
const data = {
|
|
420
|
+
field: err.meta?.target ?? err.meta?.field_name,
|
|
421
|
+
constraint: "unique",
|
|
422
|
+
reason: `The value must be unique`,
|
|
423
|
+
prismaCode: err.code,
|
|
424
|
+
originalError: err.message,
|
|
425
|
+
requestId: ctx.id
|
|
426
|
+
};
|
|
427
|
+
logPrismaError.bind(this)(ctx, errorType, 409, message, data);
|
|
428
|
+
throw new DBConstraintError(message, errorType, data);
|
|
403
429
|
},
|
|
404
|
-
P2003
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
);
|
|
430
|
+
P2003(err, ctx) {
|
|
431
|
+
const errorType = "FOREIGN_KEY_VIOLATION";
|
|
432
|
+
const message = "Foreign key constraint failed";
|
|
433
|
+
const data = {
|
|
434
|
+
field: err.meta?.field_name,
|
|
435
|
+
original: err.message,
|
|
436
|
+
ctx: ctx.id
|
|
437
|
+
};
|
|
438
|
+
logPrismaError.bind(this)(ctx, errorType, 409, message, data);
|
|
439
|
+
throw new DBConstraintError(message, errorType, data);
|
|
414
440
|
},
|
|
415
|
-
P2014
|
|
441
|
+
P2014(err, ctx) {
|
|
416
442
|
throw new DBConstraintError(
|
|
417
443
|
"Invalid relation reference",
|
|
418
444
|
"INVALID_RELATION",
|
|
@@ -423,21 +449,21 @@ var prismaErrorHandlers = {
|
|
|
423
449
|
}
|
|
424
450
|
);
|
|
425
451
|
},
|
|
426
|
-
P2000
|
|
452
|
+
P2000(err, ctx) {
|
|
427
453
|
throw new DBValidationError("Value too long for column", "VALUE_TOO_LONG", {
|
|
428
454
|
column: err.meta?.column_name,
|
|
429
455
|
original: err.message,
|
|
430
456
|
ctx: ctx.id
|
|
431
457
|
});
|
|
432
458
|
},
|
|
433
|
-
P2001
|
|
459
|
+
P2001(err, ctx) {
|
|
434
460
|
throw new DBNotFoundError("Record not found in where condition", {
|
|
435
461
|
model: err.meta?.model_name,
|
|
436
462
|
original: err.message,
|
|
437
463
|
ctx: ctx.id
|
|
438
464
|
});
|
|
439
465
|
},
|
|
440
|
-
P2004
|
|
466
|
+
P2004(err, ctx) {
|
|
441
467
|
throw new DBConstraintError(
|
|
442
468
|
"Database constraint failed",
|
|
443
469
|
"CONSTRAINT_FAILED",
|
|
@@ -448,28 +474,28 @@ var prismaErrorHandlers = {
|
|
|
448
474
|
}
|
|
449
475
|
);
|
|
450
476
|
},
|
|
451
|
-
P2021
|
|
477
|
+
P2021(err, ctx) {
|
|
452
478
|
throw new DBError("Table does not exist", 500, "TABLE_NOT_FOUND", {
|
|
453
479
|
table: err.meta?.table,
|
|
454
480
|
original: err.message,
|
|
455
481
|
ctx: ctx.id
|
|
456
482
|
});
|
|
457
483
|
},
|
|
458
|
-
P2022
|
|
484
|
+
P2022(err, ctx) {
|
|
459
485
|
throw new DBError("Column does not exist", 500, "COLUMN_NOT_FOUND", {
|
|
460
486
|
column: err.meta?.column,
|
|
461
487
|
original: err.message,
|
|
462
488
|
ctx: ctx.id
|
|
463
489
|
});
|
|
464
490
|
},
|
|
465
|
-
P2006
|
|
491
|
+
P2006(err, ctx) {
|
|
466
492
|
throw new DBValidationError("Invalid value for field", "INVALID_VALUE", {
|
|
467
493
|
field: err.meta?.field_name,
|
|
468
494
|
original: err.message,
|
|
469
495
|
ctx: ctx.id
|
|
470
496
|
});
|
|
471
497
|
},
|
|
472
|
-
P2007
|
|
498
|
+
P2007(err, ctx) {
|
|
473
499
|
throw new DBValidationError(
|
|
474
500
|
"Data validation error",
|
|
475
501
|
"DATA_VALIDATION_ERROR",
|
|
@@ -479,13 +505,13 @@ var prismaErrorHandlers = {
|
|
|
479
505
|
}
|
|
480
506
|
);
|
|
481
507
|
},
|
|
482
|
-
P2008
|
|
508
|
+
P2008(err, ctx) {
|
|
483
509
|
throw new DBError("Failed to parse the query", 400, "QUERY_PARSE_ERROR", {
|
|
484
510
|
original: err.message,
|
|
485
511
|
ctx: ctx.id
|
|
486
512
|
});
|
|
487
513
|
},
|
|
488
|
-
P2009
|
|
514
|
+
P2009(err, ctx) {
|
|
489
515
|
throw new DBError(
|
|
490
516
|
"Failed to validate the query",
|
|
491
517
|
400,
|
|
@@ -496,14 +522,14 @@ var prismaErrorHandlers = {
|
|
|
496
522
|
}
|
|
497
523
|
);
|
|
498
524
|
},
|
|
499
|
-
P2010
|
|
525
|
+
P2010(err, ctx) {
|
|
500
526
|
throw new DBError("Raw query failed", 500, "RAW_QUERY_FAILED", {
|
|
501
527
|
code: err.meta?.code,
|
|
502
528
|
original: err.message,
|
|
503
529
|
ctx: ctx.id
|
|
504
530
|
});
|
|
505
531
|
},
|
|
506
|
-
P2011
|
|
532
|
+
P2011(err, ctx) {
|
|
507
533
|
throw new DBConstraintError(
|
|
508
534
|
"Null constraint violation",
|
|
509
535
|
"NULL_CONSTRAINT_VIOLATION",
|
|
@@ -514,7 +540,7 @@ var prismaErrorHandlers = {
|
|
|
514
540
|
}
|
|
515
541
|
);
|
|
516
542
|
},
|
|
517
|
-
P2012
|
|
543
|
+
P2012(err, ctx) {
|
|
518
544
|
throw new DBValidationError(
|
|
519
545
|
"Missing a required value",
|
|
520
546
|
"MISSING_REQUIRED_VALUE",
|
|
@@ -525,7 +551,7 @@ var prismaErrorHandlers = {
|
|
|
525
551
|
}
|
|
526
552
|
);
|
|
527
553
|
},
|
|
528
|
-
P2013
|
|
554
|
+
P2013(err, ctx) {
|
|
529
555
|
throw new DBValidationError(
|
|
530
556
|
"Missing the required argument",
|
|
531
557
|
"MISSING_REQUIRED_ARGUMENT",
|
|
@@ -536,13 +562,13 @@ var prismaErrorHandlers = {
|
|
|
536
562
|
}
|
|
537
563
|
);
|
|
538
564
|
},
|
|
539
|
-
P2015
|
|
565
|
+
P2015(err, ctx) {
|
|
540
566
|
throw new DBNotFoundError("Related record not found", {
|
|
541
567
|
original: err.message,
|
|
542
568
|
ctx: ctx.id
|
|
543
569
|
});
|
|
544
570
|
},
|
|
545
|
-
P2016
|
|
571
|
+
P2016(err, ctx) {
|
|
546
572
|
throw new DBError(
|
|
547
573
|
"Query interpretation error",
|
|
548
574
|
400,
|
|
@@ -553,7 +579,7 @@ var prismaErrorHandlers = {
|
|
|
553
579
|
}
|
|
554
580
|
);
|
|
555
581
|
},
|
|
556
|
-
P2017
|
|
582
|
+
P2017(err, ctx) {
|
|
557
583
|
throw new DBConstraintError(
|
|
558
584
|
"Records relation violation",
|
|
559
585
|
"RELATION_VIOLATION",
|
|
@@ -564,25 +590,25 @@ var prismaErrorHandlers = {
|
|
|
564
590
|
}
|
|
565
591
|
);
|
|
566
592
|
},
|
|
567
|
-
P2018
|
|
593
|
+
P2018(err, ctx) {
|
|
568
594
|
throw new DBNotFoundError("Required connected records not found", {
|
|
569
595
|
original: err.message,
|
|
570
596
|
ctx: ctx.id
|
|
571
597
|
});
|
|
572
598
|
},
|
|
573
|
-
P2019
|
|
599
|
+
P2019(err, ctx) {
|
|
574
600
|
throw new DBValidationError("Input error", "INPUT_ERROR", {
|
|
575
601
|
original: err.message,
|
|
576
602
|
ctx: ctx.id
|
|
577
603
|
});
|
|
578
604
|
},
|
|
579
|
-
P2020
|
|
605
|
+
P2020(err, ctx) {
|
|
580
606
|
throw new DBValidationError("Value out of range", "VALUE_OUT_OF_RANGE", {
|
|
581
607
|
original: err.message,
|
|
582
608
|
ctx: ctx.id
|
|
583
609
|
});
|
|
584
610
|
},
|
|
585
|
-
P2023
|
|
611
|
+
P2023(err, ctx) {
|
|
586
612
|
throw new DBError(
|
|
587
613
|
"Inconsistent column data",
|
|
588
614
|
500,
|
|
@@ -593,13 +619,16 @@ var prismaErrorHandlers = {
|
|
|
593
619
|
}
|
|
594
620
|
);
|
|
595
621
|
},
|
|
596
|
-
P2024
|
|
597
|
-
|
|
622
|
+
P2024(err, ctx) {
|
|
623
|
+
const message = "Operation timed out";
|
|
624
|
+
const data = {
|
|
598
625
|
original: err.message,
|
|
599
626
|
ctx: ctx.id
|
|
600
|
-
}
|
|
627
|
+
};
|
|
628
|
+
logPrismaError.bind(this)(ctx, "DB_TIMEOUT", 504, message, data);
|
|
629
|
+
throw new DBTimeoutError(message, data);
|
|
601
630
|
},
|
|
602
|
-
P2025
|
|
631
|
+
P2025(err, ctx) {
|
|
603
632
|
throw new DBNotFoundError("Record not found for required operation", {
|
|
604
633
|
operation: err.meta?.operation_name,
|
|
605
634
|
model: err.meta?.model_name,
|
|
@@ -607,14 +636,14 @@ var prismaErrorHandlers = {
|
|
|
607
636
|
ctx: ctx.id
|
|
608
637
|
});
|
|
609
638
|
},
|
|
610
|
-
P2026
|
|
639
|
+
P2026(err, ctx) {
|
|
611
640
|
throw new DBError("Unsupported feature", 501, "UNSUPPORTED_FEATURE", {
|
|
612
641
|
feature: err.meta?.feature,
|
|
613
642
|
original: err.message,
|
|
614
643
|
ctx: ctx.id
|
|
615
644
|
});
|
|
616
645
|
},
|
|
617
|
-
P2027
|
|
646
|
+
P2027(err, ctx) {
|
|
618
647
|
throw new DBError(
|
|
619
648
|
"Multiple database errors during execution",
|
|
620
649
|
500,
|
|
@@ -625,13 +654,13 @@ var prismaErrorHandlers = {
|
|
|
625
654
|
}
|
|
626
655
|
);
|
|
627
656
|
},
|
|
628
|
-
P2028
|
|
657
|
+
P2028(err, ctx) {
|
|
629
658
|
throw new DBTransactionError("Transaction API error", {
|
|
630
659
|
original: err.message,
|
|
631
660
|
ctx: ctx.id
|
|
632
661
|
});
|
|
633
662
|
},
|
|
634
|
-
P2030
|
|
663
|
+
P2030(err, ctx) {
|
|
635
664
|
throw new DBError(
|
|
636
665
|
"Cannot find fulltext index",
|
|
637
666
|
500,
|
|
@@ -642,77 +671,130 @@ var prismaErrorHandlers = {
|
|
|
642
671
|
}
|
|
643
672
|
);
|
|
644
673
|
},
|
|
645
|
-
P2033
|
|
674
|
+
P2033(err, ctx) {
|
|
646
675
|
throw new DBValidationError("Number out of range", "NUMBER_OUT_OF_RANGE", {
|
|
647
676
|
field: err.meta?.field_name,
|
|
648
677
|
original: err.message,
|
|
649
678
|
ctx: ctx.id
|
|
650
679
|
});
|
|
651
680
|
},
|
|
652
|
-
P2034
|
|
681
|
+
P2034(err, ctx) {
|
|
653
682
|
throw new DBTransactionError("Transaction conflict", {
|
|
654
683
|
original: err.message,
|
|
655
684
|
ctx: ctx.id
|
|
656
685
|
});
|
|
657
686
|
}
|
|
658
687
|
};
|
|
659
|
-
|
|
660
|
-
const { ctx,
|
|
688
|
+
function prismaErrorHandler(err, info) {
|
|
689
|
+
const { ctx, action } = info;
|
|
661
690
|
if (err instanceof PrismaClientValidationError) {
|
|
662
|
-
|
|
691
|
+
const errorType = "INVALID_INPUT_DATA";
|
|
692
|
+
const message = "Invalid input data";
|
|
693
|
+
const data = {
|
|
663
694
|
original: err.message,
|
|
664
695
|
ctx: ctx.id,
|
|
665
|
-
service:
|
|
696
|
+
service: this.name,
|
|
666
697
|
action: action?.name
|
|
698
|
+
};
|
|
699
|
+
this.logger.warn("Database Validation Error", {
|
|
700
|
+
type: errorType,
|
|
701
|
+
message,
|
|
702
|
+
requestId: ctx.id,
|
|
703
|
+
service: this.name,
|
|
704
|
+
action: action?.name,
|
|
705
|
+
error: err.message
|
|
667
706
|
});
|
|
707
|
+
throw new DBValidationError(message, errorType, data);
|
|
668
708
|
}
|
|
669
709
|
if (err instanceof PrismaClientInitializationError) {
|
|
670
|
-
|
|
710
|
+
const message = "Database initialization failed";
|
|
711
|
+
const data = {
|
|
671
712
|
original: err.message,
|
|
672
713
|
ctx: ctx.id,
|
|
673
|
-
service:
|
|
714
|
+
service: this.name,
|
|
674
715
|
action: action?.name
|
|
716
|
+
};
|
|
717
|
+
this.logger.error("Database Connection Error", {
|
|
718
|
+
type: "DB_CONNECTION_ERROR",
|
|
719
|
+
message,
|
|
720
|
+
requestId: ctx.id,
|
|
721
|
+
service: this.name,
|
|
722
|
+
action: action?.name,
|
|
723
|
+
error: err.message
|
|
675
724
|
});
|
|
725
|
+
throw new DBConnectionError(message, data);
|
|
676
726
|
}
|
|
677
727
|
if (err instanceof PrismaClientUnknownRequestError) {
|
|
678
|
-
|
|
728
|
+
const errorType = "DB_UNKNOWN_ERROR";
|
|
729
|
+
const message = "Unknown database error";
|
|
730
|
+
const data = {
|
|
679
731
|
original: err.message,
|
|
680
732
|
ctx: ctx.id,
|
|
681
|
-
service:
|
|
733
|
+
service: this.name,
|
|
682
734
|
action: action?.name
|
|
735
|
+
};
|
|
736
|
+
this.logger.error("Unknown Database Error", {
|
|
737
|
+
type: errorType,
|
|
738
|
+
message,
|
|
739
|
+
requestId: ctx.id,
|
|
740
|
+
service: this.name,
|
|
741
|
+
action: action?.name,
|
|
742
|
+
error: err.message,
|
|
743
|
+
stack: err.stack
|
|
683
744
|
});
|
|
745
|
+
throw new DBError(message, 500, errorType, data);
|
|
684
746
|
}
|
|
685
747
|
if (err instanceof PrismaClientRustPanicError) {
|
|
686
|
-
|
|
748
|
+
const errorType = "DB_ENGINE_PANIC";
|
|
749
|
+
const message = "Database engine panic";
|
|
750
|
+
const data = {
|
|
687
751
|
original: err.message,
|
|
688
752
|
ctx: ctx.id,
|
|
689
|
-
service:
|
|
753
|
+
service: this.name,
|
|
690
754
|
action: action?.name
|
|
755
|
+
};
|
|
756
|
+
this.logger.fatal("Database Engine Panic", {
|
|
757
|
+
type: errorType,
|
|
758
|
+
message,
|
|
759
|
+
requestId: ctx.id,
|
|
760
|
+
service: this.name,
|
|
761
|
+
action: action?.name,
|
|
762
|
+
error: err.message,
|
|
763
|
+
stack: err.stack
|
|
691
764
|
});
|
|
765
|
+
throw new DBError(message, 500, errorType, data);
|
|
692
766
|
}
|
|
693
767
|
if (err instanceof PrismaClientKnownRequestError) {
|
|
694
768
|
const handler = prismaErrorHandlers[err.code];
|
|
695
769
|
if (handler) {
|
|
696
|
-
return handler(err, ctx);
|
|
770
|
+
return handler.bind(this)(err, ctx);
|
|
697
771
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
772
|
+
const errorType = "DB_CONSTRAINT_ERROR";
|
|
773
|
+
const message = "Unknown database constraint error";
|
|
774
|
+
const data = {
|
|
775
|
+
code: err.code,
|
|
776
|
+
meta: err.meta,
|
|
777
|
+
original: err.message,
|
|
778
|
+
ctx: ctx.id,
|
|
779
|
+
service: this.name,
|
|
780
|
+
action: action?.name
|
|
781
|
+
};
|
|
782
|
+
this.logger.error("Unknown Database Constraint Error", {
|
|
783
|
+
type: errorType,
|
|
784
|
+
prismaCode: err.code,
|
|
785
|
+
message,
|
|
786
|
+
requestId: ctx.id,
|
|
787
|
+
service: this.name,
|
|
788
|
+
action: action?.name,
|
|
789
|
+
meta: err.meta,
|
|
790
|
+
error: err.message
|
|
791
|
+
});
|
|
792
|
+
throw new DBError(message, 500, errorType, data);
|
|
711
793
|
}
|
|
712
794
|
if (err instanceof Errors.MoleculerError) {
|
|
713
795
|
throw err;
|
|
714
796
|
}
|
|
715
|
-
}
|
|
797
|
+
}
|
|
716
798
|
|
|
717
799
|
// src/middlewares/permissions.middleware.ts
|
|
718
800
|
var permissionHandlers = {
|
|
@@ -1071,6 +1153,52 @@ function DatasourceMixin(datasourceConstructors = {}) {
|
|
|
1071
1153
|
};
|
|
1072
1154
|
}
|
|
1073
1155
|
|
|
1156
|
+
// src/utils/error-logger.ts
|
|
1157
|
+
function getErrorLogLevel(code) {
|
|
1158
|
+
if (typeof code === "number") {
|
|
1159
|
+
if (code >= 500) return "error";
|
|
1160
|
+
if (code >= 400) return "warn";
|
|
1161
|
+
return "info";
|
|
1162
|
+
}
|
|
1163
|
+
if (typeof code === "string") {
|
|
1164
|
+
const criticalErrors = [
|
|
1165
|
+
"DB_ENGINE_PANIC",
|
|
1166
|
+
"SYSTEM_FAILURE",
|
|
1167
|
+
"CRITICAL_ERROR"
|
|
1168
|
+
];
|
|
1169
|
+
if (criticalErrors.includes(code)) return "fatal";
|
|
1170
|
+
const systemErrors = [
|
|
1171
|
+
"DB_CONNECTION_ERROR",
|
|
1172
|
+
"INTERNAL_ERROR",
|
|
1173
|
+
"TRANSACTION_ERROR"
|
|
1174
|
+
];
|
|
1175
|
+
if (systemErrors.includes(code)) return "error";
|
|
1176
|
+
}
|
|
1177
|
+
return "warn";
|
|
1178
|
+
}
|
|
1179
|
+
function sanitizeErrorData(data) {
|
|
1180
|
+
if (!data) return data;
|
|
1181
|
+
const sensitiveKeys = [
|
|
1182
|
+
"password",
|
|
1183
|
+
"token",
|
|
1184
|
+
"secret",
|
|
1185
|
+
"apiKey",
|
|
1186
|
+
"authorization"
|
|
1187
|
+
];
|
|
1188
|
+
if (typeof data === "object") {
|
|
1189
|
+
const sanitized = Array.isArray(data) ? [...data] : { ...data };
|
|
1190
|
+
for (const key in sanitized) {
|
|
1191
|
+
if (sensitiveKeys.some((k) => key.toLowerCase().includes(k.toLowerCase()))) {
|
|
1192
|
+
sanitized[key] = "[REDACTED]";
|
|
1193
|
+
} else if (typeof sanitized[key] === "object") {
|
|
1194
|
+
sanitized[key] = sanitizeErrorData(sanitized[key]);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return sanitized;
|
|
1198
|
+
}
|
|
1199
|
+
return data;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1074
1202
|
// src/utils/index.ts
|
|
1075
1203
|
function omit(obj, keys) {
|
|
1076
1204
|
const result = { ...obj };
|
|
@@ -1852,18 +1980,51 @@ var configs = {
|
|
|
1852
1980
|
PermissionsMiddleware,
|
|
1853
1981
|
ContextHelpersMiddleware
|
|
1854
1982
|
],
|
|
1855
|
-
errorHandler
|
|
1856
|
-
|
|
1857
|
-
|
|
1983
|
+
errorHandler(err, info) {
|
|
1984
|
+
const { ctx, action } = info;
|
|
1985
|
+
try {
|
|
1986
|
+
prismaErrorHandler.bind(this)(err, info);
|
|
1987
|
+
} catch (handledError) {
|
|
1988
|
+
if (handledError instanceof Errors.MoleculerError) {
|
|
1989
|
+
throw handledError;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
const statusCode = err.code ?? err.statusCode ?? 500;
|
|
1993
|
+
const errorType = err.type ?? "INTERNAL_ERROR";
|
|
1994
|
+
const isSystemError = statusCode >= 500;
|
|
1995
|
+
const logData = {
|
|
1996
|
+
type: errorType,
|
|
1997
|
+
message: err.message,
|
|
1998
|
+
requestId: ctx.id,
|
|
1999
|
+
service: this.name,
|
|
2000
|
+
action: action?.name,
|
|
2001
|
+
params: ctx.params,
|
|
2002
|
+
caller: ctx.caller,
|
|
2003
|
+
stack: isSystemError ? err.stack : void 0,
|
|
2004
|
+
nodeID: ctx.nodeID,
|
|
2005
|
+
level: ctx.level,
|
|
2006
|
+
tracing: ctx.tracing
|
|
2007
|
+
};
|
|
2008
|
+
Object.keys(logData).forEach(
|
|
2009
|
+
(key) => logData[key] === void 0 && delete logData[key]
|
|
2010
|
+
);
|
|
2011
|
+
if (isSystemError) {
|
|
2012
|
+
this.logger.error("Unhandled Service Error", logData);
|
|
2013
|
+
} else {
|
|
2014
|
+
this.logger.warn("Service Error", logData);
|
|
2015
|
+
}
|
|
2016
|
+
if (err instanceof Errors.MoleculerError) {
|
|
2017
|
+
throw err;
|
|
2018
|
+
}
|
|
1858
2019
|
throw new Errors.MoleculerError(
|
|
1859
2020
|
err.message || "Internal server error",
|
|
1860
|
-
|
|
1861
|
-
|
|
2021
|
+
statusCode,
|
|
2022
|
+
errorType,
|
|
1862
2023
|
{
|
|
1863
2024
|
original: err.message,
|
|
1864
|
-
stack: err.stack,
|
|
2025
|
+
stack: isSystemError ? err.stack : void 0,
|
|
1865
2026
|
ctx: ctx.id,
|
|
1866
|
-
service:
|
|
2027
|
+
service: this.name,
|
|
1867
2028
|
action: action?.name
|
|
1868
2029
|
}
|
|
1869
2030
|
);
|
|
@@ -2444,4 +2605,4 @@ var retryExtension = {
|
|
|
2444
2605
|
}
|
|
2445
2606
|
};
|
|
2446
2607
|
|
|
2447
|
-
export { AbstractDatasource, AuthenticationError, CHANNELS, ContextHelpersMiddleware, CreateHealthCheckMiddleware, DBConnectionError, DBConstraintError, DBError, DBNotFoundError, DBTimeoutError, DBTransactionError, DBValidationError, DEFAULT_DATASOURCE_CACHE_TTL, DatasourceMixin, HEALTH_CHECK_DEFAULTS, INTEGRATION_CHANNELS, IntegrationCapability, IntegrationPlatform, IntegrationStatus, MemoizeMixin, MessageContentType, NAMESPACE, PERMISSIONS, PermissionError, PermissionsMiddleware, PrismaDatasource, PrismaPgDatasource, REDIS_URL, ROLE_PERMISSIONS, TenantError, UserRole, createDatasourceMiddleware, createTenantExtension, defineIntegration, defineService, env_default as env, gatewayErrorHandler, isDev, isProd, isTest, moleculer_default as moleculer, nodeEnv, omit, prismaErrorHandler, retryExtension, softDeleteExtension };
|
|
2608
|
+
export { AbstractDatasource, AuthenticationError, CHANNELS, ContextHelpersMiddleware, CreateHealthCheckMiddleware, DBConnectionError, DBConstraintError, DBError, DBNotFoundError, DBTimeoutError, DBTransactionError, DBValidationError, DEFAULT_DATASOURCE_CACHE_TTL, DatasourceMixin, HEALTH_CHECK_DEFAULTS, INTEGRATION_CHANNELS, IntegrationCapability, IntegrationPlatform, IntegrationStatus, MemoizeMixin, MessageContentType, NAMESPACE, PERMISSIONS, PermissionError, PermissionsMiddleware, PrismaDatasource, PrismaPgDatasource, REDIS_URL, ROLE_PERMISSIONS, TenantError, UserRole, createDatasourceMiddleware, createTenantExtension, defineIntegration, defineService, env_default as env, gatewayErrorHandler, getErrorLogLevel, isDev, isProd, isTest, moleculer_default as moleculer, nodeEnv, omit, prismaErrorHandler, retryExtension, sanitizeErrorData, softDeleteExtension };
|