@platform-modules/civil-aviation-authority 2.3.226 → 2.3.228

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 CHANGED
@@ -395,3 +395,4 @@ export * from './models/ContractServiceRequestModel';
395
395
  export * from './models/SlaConfigModel';
396
396
  export * from './models/SlaRequestModel';
397
397
  export * from './models/ServiceSlaApprovalModel';
398
+ export * from './sla/sla-table-sync.service';
package/dist/index.js CHANGED
@@ -574,3 +574,4 @@ __exportStar(require("./models/ContractServiceRequestModel"), exports);
574
574
  __exportStar(require("./models/SlaConfigModel"), exports);
575
575
  __exportStar(require("./models/SlaRequestModel"), exports);
576
576
  __exportStar(require("./models/ServiceSlaApprovalModel"), exports);
577
+ __exportStar(require("./sla/sla-table-sync.service"), exports);
@@ -41,8 +41,7 @@ export declare class HumanResourceAnnualPlanningRequest extends BaseModel {
41
41
  emotional_intelligence_rating: string | null;
42
42
  emotional_intelligence_other: string | null;
43
43
  comment: string | null;
44
- extension_number: string | null;
45
44
  quarter: Quarter | null;
46
45
  year: number | null;
47
- constructor(user_id: number, status?: HumanResourceAnnualPlanningRequestStatus, service_id?: number | null, sub_service_id?: number | null, req_user_department_id?: number | null, req_user_section_id?: number | null, req_user_position_id?: number | null, description?: string | null, reviewer_user_id?: number | null, assigned_to_user_id?: number | null, assigned_at?: Date | null, workflow_execution_id?: string | null, employee_name?: string | null, employee_id?: string | null, current_position?: string | null, skills?: string | null, work_experience?: number | null, productivity_rating?: string | null, productivity_other?: string | null, behavior_rating?: string | null, behavior_other?: string | null, leadership_rating?: string | null, leadership_other?: string | null, emotional_intelligence_rating?: string | null, emotional_intelligence_other?: string | null, comment?: string | null, extension_number?: string | null, quarter?: Quarter | null, year?: number | null);
46
+ constructor(user_id: number, status?: HumanResourceAnnualPlanningRequestStatus, service_id?: number | null, sub_service_id?: number | null, req_user_department_id?: number | null, req_user_section_id?: number | null, req_user_position_id?: number | null, description?: string | null, reviewer_user_id?: number | null, assigned_to_user_id?: number | null, assigned_at?: Date | null, workflow_execution_id?: string | null, employee_name?: string | null, employee_id?: string | null, current_position?: string | null, skills?: string | null, work_experience?: number | null, productivity_rating?: string | null, productivity_other?: string | null, behavior_rating?: string | null, behavior_other?: string | null, leadership_rating?: string | null, leadership_other?: string | null, emotional_intelligence_rating?: string | null, emotional_intelligence_other?: string | null, comment?: string | null, quarter?: Quarter | null, year?: number | null);
48
47
  }
@@ -30,7 +30,7 @@ var Quarter;
30
30
  Quarter["Q4"] = "Q4"; // Oct-Dec
31
31
  })(Quarter || (exports.Quarter = Quarter = {}));
32
32
  let HumanResourceAnnualPlanningRequest = class HumanResourceAnnualPlanningRequest extends BaseModel_1.BaseModel {
33
- constructor(user_id, status = HumanResourceAnnualPlanningRequestStatus.PENDING, service_id, sub_service_id, req_user_department_id, req_user_section_id, req_user_position_id, description, reviewer_user_id, assigned_to_user_id, assigned_at, workflow_execution_id, employee_name, employee_id, current_position, skills, work_experience, productivity_rating, productivity_other, behavior_rating, behavior_other, leadership_rating, leadership_other, emotional_intelligence_rating, emotional_intelligence_other, comment, extension_number, quarter, year) {
33
+ constructor(user_id, status = HumanResourceAnnualPlanningRequestStatus.PENDING, service_id, sub_service_id, req_user_department_id, req_user_section_id, req_user_position_id, description, reviewer_user_id, assigned_to_user_id, assigned_at, workflow_execution_id, employee_name, employee_id, current_position, skills, work_experience, productivity_rating, productivity_other, behavior_rating, behavior_other, leadership_rating, leadership_other, emotional_intelligence_rating, emotional_intelligence_other, comment, quarter, year) {
34
34
  super();
35
35
  this.user_id = user_id;
36
36
  this.status = status;
@@ -58,7 +58,6 @@ let HumanResourceAnnualPlanningRequest = class HumanResourceAnnualPlanningReques
58
58
  this.emotional_intelligence_rating = emotional_intelligence_rating || null;
59
59
  this.emotional_intelligence_other = emotional_intelligence_other || null;
60
60
  this.comment = comment || null;
61
- this.extension_number = extension_number || null;
62
61
  this.quarter = quarter || null;
63
62
  this.year = year || null;
64
63
  }
@@ -168,10 +167,6 @@ __decorate([
168
167
  (0, typeorm_1.Column)({ type: "text", nullable: true }),
169
168
  __metadata("design:type", Object)
170
169
  ], HumanResourceAnnualPlanningRequest.prototype, "comment", void 0);
171
- __decorate([
172
- (0, typeorm_1.Column)({ type: "varchar", length: 50, nullable: true }),
173
- __metadata("design:type", Object)
174
- ], HumanResourceAnnualPlanningRequest.prototype, "extension_number", void 0);
175
170
  __decorate([
176
171
  (0, typeorm_1.Column)({ type: "enum", enum: Quarter, nullable: true }),
177
172
  __metadata("design:type", Object)
@@ -182,5 +177,5 @@ __decorate([
182
177
  ], HumanResourceAnnualPlanningRequest.prototype, "year", void 0);
183
178
  exports.HumanResourceAnnualPlanningRequest = HumanResourceAnnualPlanningRequest = __decorate([
184
179
  (0, typeorm_1.Entity)({ name: "human_resource_annual_planning_requests" }),
185
- __metadata("design:paramtypes", [Number, String, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object])
180
+ __metadata("design:paramtypes", [Number, String, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object])
186
181
  ], HumanResourceAnnualPlanningRequest);
@@ -19,5 +19,9 @@ export declare class Notification extends BaseModel {
19
19
  service_id: number;
20
20
  sub_service_id: number;
21
21
  route_path: string;
22
+ /** Mirrors SLA reminder metadata also stored in `content` for cron-created rows (optional DB migration). */
23
+ is_sla: boolean;
24
+ /** Remaining SLA reminder taps allowed (starts at 3 for SLA cron notifications). Optional column — see `content.sla_count`. */
25
+ sla_count: number | null;
22
26
  constructor(type: NotificationType, user_id: number, role_id: number, department_id: number, section_id: number, content: any, is_read: boolean, request_id: number, service_id: number, sub_service_id: number, route_path: string);
23
27
  }
@@ -86,6 +86,14 @@ __decorate([
86
86
  (0, typeorm_1.Column)({ type: 'varchar', length: 500, nullable: true }),
87
87
  __metadata("design:type", String)
88
88
  ], Notification.prototype, "route_path", void 0);
89
+ __decorate([
90
+ (0, typeorm_1.Column)({ type: 'boolean', default: false }),
91
+ __metadata("design:type", Boolean)
92
+ ], Notification.prototype, "is_sla", void 0);
93
+ __decorate([
94
+ (0, typeorm_1.Column)({ type: 'integer', nullable: true }),
95
+ __metadata("design:type", Object)
96
+ ], Notification.prototype, "sla_count", void 0);
89
97
  exports.Notification = Notification = __decorate([
90
98
  (0, typeorm_1.Entity)({ name: 'notification' }),
91
99
  __metadata("design:paramtypes", [String, Number, Number, Number, Number, Object, Boolean, Number, Number, Number, String])
@@ -13,6 +13,10 @@ export declare enum MediaCoverageRequired {
13
13
  export declare class SecurityAwarenessRequest extends BaseModel {
14
14
  req_user_department_id: number | null;
15
15
  req_user_section_id: number | null;
16
+ /** Target department from create payload (approval routing / reporting). */
17
+ department_id: number | null;
18
+ /** Target section from create payload; may reference a section or be omitted when "All Sections". */
19
+ section_id: number | null;
16
20
  service_id: number;
17
21
  sub_service_id: number;
18
22
  user_id: number;
@@ -24,6 +28,12 @@ export declare class SecurityAwarenessRequest extends BaseModel {
24
28
  event_date: Date | null;
25
29
  event_time: string | null;
26
30
  media_coverage_required: MediaCoverageRequired;
31
+ /** Approval payload: `is_network_support_required` → persisted here */
32
+ network_support_required: MediaCoverageRequired;
33
+ /** Approval payload: `is_public_relations_support_required` → persisted here */
34
+ public_relations_support_required: MediaCoverageRequired;
35
+ /** Approval payload: `is_training_support_required` → persisted here */
36
+ training_support_required: MediaCoverageRequired;
27
37
  status: SecurityAwarenessRequestStatus;
28
38
  workflow_execution_id: string | null;
29
39
  constructor(req_user_department_id: number | null, req_user_section_id: number | null, service_id: number, sub_service_id: number, user_id: number, title: string, date_of_submission: Date, phone_number: string, place: string | null, description: string | null, event_date: Date | null, event_time: string | null, media_coverage_required: MediaCoverageRequired, status: SecurityAwarenessRequestStatus, workflow_execution_id?: string | null);
@@ -28,6 +28,12 @@ var MediaCoverageRequired;
28
28
  let SecurityAwarenessRequest = class SecurityAwarenessRequest extends BaseModel_1.BaseModel {
29
29
  constructor(req_user_department_id, req_user_section_id, service_id, sub_service_id, user_id, title, date_of_submission, phone_number, place, description, event_date, event_time, media_coverage_required, status, workflow_execution_id) {
30
30
  super();
31
+ /** Approval payload: `is_network_support_required` → persisted here */
32
+ this.network_support_required = MediaCoverageRequired.NO;
33
+ /** Approval payload: `is_public_relations_support_required` → persisted here */
34
+ this.public_relations_support_required = MediaCoverageRequired.NO;
35
+ /** Approval payload: `is_training_support_required` → persisted here */
36
+ this.training_support_required = MediaCoverageRequired.NO;
31
37
  this.req_user_department_id = req_user_department_id ?? null;
32
38
  this.req_user_section_id = req_user_section_id ?? null;
33
39
  this.service_id = service_id;
@@ -54,6 +60,14 @@ __decorate([
54
60
  (0, typeorm_1.Column)({ type: 'int', nullable: true }),
55
61
  __metadata("design:type", Object)
56
62
  ], SecurityAwarenessRequest.prototype, "req_user_section_id", void 0);
63
+ __decorate([
64
+ (0, typeorm_1.Column)({ type: 'int', nullable: true }),
65
+ __metadata("design:type", Object)
66
+ ], SecurityAwarenessRequest.prototype, "department_id", void 0);
67
+ __decorate([
68
+ (0, typeorm_1.Column)({ type: 'int', nullable: true }),
69
+ __metadata("design:type", Object)
70
+ ], SecurityAwarenessRequest.prototype, "section_id", void 0);
57
71
  __decorate([
58
72
  (0, typeorm_1.Column)({ nullable: true }),
59
73
  __metadata("design:type", Number)
@@ -103,6 +117,33 @@ __decorate([
103
117
  }),
104
118
  __metadata("design:type", String)
105
119
  ], SecurityAwarenessRequest.prototype, "media_coverage_required", void 0);
120
+ __decorate([
121
+ (0, typeorm_1.Column)({
122
+ type: "enum",
123
+ enum: MediaCoverageRequired,
124
+ default: MediaCoverageRequired.NO,
125
+ nullable: false,
126
+ }),
127
+ __metadata("design:type", String)
128
+ ], SecurityAwarenessRequest.prototype, "network_support_required", void 0);
129
+ __decorate([
130
+ (0, typeorm_1.Column)({
131
+ type: "enum",
132
+ enum: MediaCoverageRequired,
133
+ default: MediaCoverageRequired.NO,
134
+ nullable: false,
135
+ }),
136
+ __metadata("design:type", String)
137
+ ], SecurityAwarenessRequest.prototype, "public_relations_support_required", void 0);
138
+ __decorate([
139
+ (0, typeorm_1.Column)({
140
+ type: "enum",
141
+ enum: MediaCoverageRequired,
142
+ default: MediaCoverageRequired.NO,
143
+ nullable: false,
144
+ }),
145
+ __metadata("design:type", String)
146
+ ], SecurityAwarenessRequest.prototype, "training_support_required", void 0);
106
147
  __decorate([
107
148
  (0, typeorm_1.Column)({
108
149
  type: "enum",
@@ -0,0 +1,23 @@
1
+ import { EntityManager } from "typeorm";
2
+ import { SlaRequestStatus } from "../models/SlaRequestModel";
3
+ export type PatchSlaApprovalTableInput = Partial<{
4
+ approval_status: string;
5
+ approver_user_id: number | null;
6
+ approver_role_id: number | null;
7
+ department_id: number | null;
8
+ section_id: number | null;
9
+ level: number;
10
+ }>;
11
+ export type PatchSlaRequestTableInput = Partial<{
12
+ status: SlaRequestStatus | string;
13
+ workflow_execution_id: string | null;
14
+ }>;
15
+ /**
16
+ * TypeORM patches for `sla_approval` and `sla_requests` by the keys used at insert time
17
+ * (`source_approval_id` and native `request_id`). Safe to call from any service that shares the DB;
18
+ * failures are swallowed so missing SLA rows never block business transactions.
19
+ */
20
+ export declare class SlaTableSyncService {
21
+ static patchSlaApprovalBySourceApprovalId(manager: EntityManager, sourceApprovalId: number, patch: PatchSlaApprovalTableInput, updatedBy?: number | null): Promise<void>;
22
+ static patchSlaRequestByNativeRequestId(manager: EntityManager, nativeRequestId: number, patch: PatchSlaRequestTableInput, updatedBy?: number | null): Promise<void>;
23
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlaTableSyncService = void 0;
4
+ const ServiceSlaApprovalModel_1 = require("../models/ServiceSlaApprovalModel");
5
+ const SlaRequestModel_1 = require("../models/SlaRequestModel");
6
+ function stripUndefined(obj) {
7
+ const out = {};
8
+ for (const key of Object.keys(obj)) {
9
+ const v = obj[key];
10
+ if (v !== undefined) {
11
+ out[key] = v;
12
+ }
13
+ }
14
+ return out;
15
+ }
16
+ /**
17
+ * TypeORM patches for `sla_approval` and `sla_requests` by the keys used at insert time
18
+ * (`source_approval_id` and native `request_id`). Safe to call from any service that shares the DB;
19
+ * failures are swallowed so missing SLA rows never block business transactions.
20
+ */
21
+ class SlaTableSyncService {
22
+ static async patchSlaApprovalBySourceApprovalId(manager, sourceApprovalId, patch, updatedBy) {
23
+ if (!Number.isFinite(sourceApprovalId)) {
24
+ return;
25
+ }
26
+ try {
27
+ const setPayload = {
28
+ ...stripUndefined(patch),
29
+ updated_at: new Date()
30
+ };
31
+ if (updatedBy != null) {
32
+ setPayload.updated_by = updatedBy;
33
+ }
34
+ await manager.getRepository(ServiceSlaApprovalModel_1.ServiceSlaApproval).update({ source_approval_id: sourceApprovalId, is_deleted: false }, setPayload);
35
+ }
36
+ catch {
37
+ // non-fatal
38
+ }
39
+ }
40
+ static async patchSlaRequestByNativeRequestId(manager, nativeRequestId, patch, updatedBy) {
41
+ if (!Number.isFinite(nativeRequestId) || nativeRequestId < 1) {
42
+ return;
43
+ }
44
+ try {
45
+ const setPayload = {
46
+ ...stripUndefined(patch),
47
+ updated_at: new Date()
48
+ };
49
+ if (updatedBy != null) {
50
+ setPayload.updated_by = updatedBy;
51
+ }
52
+ await manager.getRepository(SlaRequestModel_1.SlaRequest).update({ request_id: nativeRequestId, is_deleted: false }, setPayload);
53
+ }
54
+ catch {
55
+ // non-fatal
56
+ }
57
+ }
58
+ }
59
+ exports.SlaTableSyncService = SlaTableSyncService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platform-modules/civil-aviation-authority",
3
- "version": "2.3.226",
3
+ "version": "2.3.228",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
package/src/index.ts CHANGED
@@ -480,4 +480,5 @@ export * from './models/ContractServiceRequestModel';
480
480
 
481
481
  export * from './models/SlaConfigModel';
482
482
  export * from './models/SlaRequestModel';
483
- export * from './models/ServiceSlaApprovalModel';
483
+ export * from './models/ServiceSlaApprovalModel';
484
+ export * from './sla/sla-table-sync.service';
@@ -99,9 +99,6 @@ export class HumanResourceAnnualPlanningRequest extends BaseModel {
99
99
  @Column({ type: "text", nullable: true })
100
100
  comment: string | null;
101
101
 
102
- @Column({ type: "varchar", length: 50, nullable: true })
103
- extension_number: string | null;
104
-
105
102
  @Column({ type: "enum", enum: Quarter, nullable: true })
106
103
  quarter: Quarter | null;
107
104
 
@@ -135,7 +132,6 @@ export class HumanResourceAnnualPlanningRequest extends BaseModel {
135
132
  emotional_intelligence_rating?: string | null,
136
133
  emotional_intelligence_other?: string | null,
137
134
  comment?: string | null,
138
- extension_number?: string | null,
139
135
  quarter?: Quarter | null,
140
136
  year?: number | null
141
137
  ) {
@@ -166,7 +162,6 @@ export class HumanResourceAnnualPlanningRequest extends BaseModel {
166
162
  this.emotional_intelligence_rating = emotional_intelligence_rating || null;
167
163
  this.emotional_intelligence_other = emotional_intelligence_other || null;
168
164
  this.comment = comment || null;
169
- this.extension_number = extension_number || null;
170
165
  this.quarter = quarter || null;
171
166
  this.year = year || null;
172
167
  }
@@ -51,6 +51,14 @@ export class Notification extends BaseModel {
51
51
  @Column({ type: 'varchar', length: 500, nullable: true })
52
52
  route_path: string;
53
53
 
54
+ /** Mirrors SLA reminder metadata also stored in `content` for cron-created rows (optional DB migration). */
55
+ @Column({ type: 'boolean', default: false })
56
+ is_sla: boolean;
57
+
58
+ /** Remaining SLA reminder taps allowed (starts at 3 for SLA cron notifications). Optional column — see `content.sla_count`. */
59
+ @Column({ type: 'integer', nullable: true })
60
+ sla_count: number | null;
61
+
54
62
  constructor(
55
63
  type: NotificationType,
56
64
  user_id: number,
@@ -23,6 +23,14 @@ export class SecurityAwarenessRequest extends BaseModel {
23
23
  @Column({ type: 'int', nullable: true })
24
24
  req_user_section_id: number | null;
25
25
 
26
+ /** Target department from create payload (approval routing / reporting). */
27
+ @Column({ type: 'int', nullable: true })
28
+ department_id: number | null;
29
+
30
+ /** Target section from create payload; may reference a section or be omitted when "All Sections". */
31
+ @Column({ type: 'int', nullable: true })
32
+ section_id: number | null;
33
+
26
34
  @Column({ nullable: true })
27
35
  service_id: number;
28
36
 
@@ -61,6 +69,33 @@ export class SecurityAwarenessRequest extends BaseModel {
61
69
  })
62
70
  media_coverage_required: MediaCoverageRequired;
63
71
 
72
+ /** Approval payload: `is_network_support_required` → persisted here */
73
+ @Column({
74
+ type: "enum",
75
+ enum: MediaCoverageRequired,
76
+ default: MediaCoverageRequired.NO,
77
+ nullable: false,
78
+ })
79
+ network_support_required: MediaCoverageRequired = MediaCoverageRequired.NO;
80
+
81
+ /** Approval payload: `is_public_relations_support_required` → persisted here */
82
+ @Column({
83
+ type: "enum",
84
+ enum: MediaCoverageRequired,
85
+ default: MediaCoverageRequired.NO,
86
+ nullable: false,
87
+ })
88
+ public_relations_support_required: MediaCoverageRequired = MediaCoverageRequired.NO;
89
+
90
+ /** Approval payload: `is_training_support_required` → persisted here */
91
+ @Column({
92
+ type: "enum",
93
+ enum: MediaCoverageRequired,
94
+ default: MediaCoverageRequired.NO,
95
+ nullable: false,
96
+ })
97
+ training_support_required: MediaCoverageRequired = MediaCoverageRequired.NO;
98
+
64
99
  @Column({
65
100
  type: "enum",
66
101
  enum: SecurityAwarenessRequestStatus,
@@ -0,0 +1,87 @@
1
+ import { EntityManager } from "typeorm";
2
+ import { ServiceSlaApproval } from "../models/ServiceSlaApprovalModel";
3
+ import { SlaRequest, SlaRequestStatus } from "../models/SlaRequestModel";
4
+
5
+ export type PatchSlaApprovalTableInput = Partial<{
6
+ approval_status: string;
7
+ approver_user_id: number | null;
8
+ approver_role_id: number | null;
9
+ department_id: number | null;
10
+ section_id: number | null;
11
+ level: number;
12
+ }>;
13
+
14
+ export type PatchSlaRequestTableInput = Partial<{
15
+ status: SlaRequestStatus | string;
16
+ workflow_execution_id: string | null;
17
+ }>;
18
+
19
+ function stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {
20
+ const out: Partial<T> = {};
21
+ for (const key of Object.keys(obj)) {
22
+ const v = obj[key];
23
+ if (v !== undefined) {
24
+ (out as Record<string, unknown>)[key] = v;
25
+ }
26
+ }
27
+ return out;
28
+ }
29
+
30
+ /**
31
+ * TypeORM patches for `sla_approval` and `sla_requests` by the keys used at insert time
32
+ * (`source_approval_id` and native `request_id`). Safe to call from any service that shares the DB;
33
+ * failures are swallowed so missing SLA rows never block business transactions.
34
+ */
35
+ export class SlaTableSyncService {
36
+ static async patchSlaApprovalBySourceApprovalId(
37
+ manager: EntityManager,
38
+ sourceApprovalId: number,
39
+ patch: PatchSlaApprovalTableInput,
40
+ updatedBy?: number | null
41
+ ): Promise<void> {
42
+ if (!Number.isFinite(sourceApprovalId)) {
43
+ return;
44
+ }
45
+ try {
46
+ const setPayload: Record<string, unknown> = {
47
+ ...stripUndefined(patch as Record<string, unknown>),
48
+ updated_at: new Date()
49
+ };
50
+ if (updatedBy != null) {
51
+ setPayload.updated_by = updatedBy;
52
+ }
53
+ await manager.getRepository(ServiceSlaApproval).update(
54
+ { source_approval_id: sourceApprovalId, is_deleted: false },
55
+ setPayload as any
56
+ );
57
+ } catch {
58
+ // non-fatal
59
+ }
60
+ }
61
+
62
+ static async patchSlaRequestByNativeRequestId(
63
+ manager: EntityManager,
64
+ nativeRequestId: number,
65
+ patch: PatchSlaRequestTableInput,
66
+ updatedBy?: number | null
67
+ ): Promise<void> {
68
+ if (!Number.isFinite(nativeRequestId) || nativeRequestId < 1) {
69
+ return;
70
+ }
71
+ try {
72
+ const setPayload: Record<string, unknown> = {
73
+ ...stripUndefined(patch as Record<string, unknown>),
74
+ updated_at: new Date()
75
+ };
76
+ if (updatedBy != null) {
77
+ setPayload.updated_by = updatedBy;
78
+ }
79
+ await manager.getRepository(SlaRequest).update(
80
+ { request_id: nativeRequestId, is_deleted: false },
81
+ setPayload as any
82
+ );
83
+ } catch {
84
+ // non-fatal
85
+ }
86
+ }
87
+ }