@itwin/imodel-transformer 2.0.0-dev.26 → 2.0.0-dev.28

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.
@@ -12,6 +12,7 @@ const path = require("path");
12
12
  const Semver = require("semver");
13
13
  const nodeAssert = require("assert");
14
14
  const core_bentley_1 = require("@itwin/core-bentley");
15
+ const ECSchemaMetaData = require("@itwin/ecschema-metadata");
15
16
  const core_geometry_1 = require("@itwin/core-geometry");
16
17
  const core_backend_1 = require("@itwin/core-backend");
17
18
  const core_common_1 = require("@itwin/core-common");
@@ -23,6 +24,7 @@ const EntityUnifier_1 = require("./EntityUnifier");
23
24
  const Algo_1 = require("./Algo");
24
25
  const SyncTypeResolver_1 = require("./SyncTypeResolver");
25
26
  const ProvenanceManager_1 = require("./ProvenanceManager");
27
+ const IModelTransformerError_1 = require("./IModelTransformerError");
26
28
  const loggerCategory = TransformerLoggerCategory_1.TransformerLoggerCategory.IModelTransformer;
27
29
  /**
28
30
  * Apply a function to each Id64 in a supported container type of Id64s.
@@ -49,10 +51,16 @@ function mapId64(idContainer, func) {
49
51
  results.push(func(idContainer.id));
50
52
  }
51
53
  else {
52
- throw Error([
53
- `Id64 container '${JSON.stringify(idContainer)}' is unsupported.`,
54
- "Currently only singular Id64 strings or prop-like objects containing an 'id' property are supported.",
55
- ].join("\n"));
54
+ core_bentley_1.ITwinError.throwError({
55
+ iTwinErrorId: {
56
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
57
+ key: IModelTransformerError_1.IModelTransformerError.InvalidEntityReference,
58
+ },
59
+ message: [
60
+ `Id64 container '${JSON.stringify(idContainer)}' is unsupported.`,
61
+ "Currently only singular Id64 strings or prop-like objects containing an 'id' property are supported.",
62
+ ].join("\n"),
63
+ });
56
64
  }
57
65
  return results;
58
66
  }
@@ -219,13 +227,23 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
219
227
  validateSharedOptionsMatch() {
220
228
  if (Boolean(this._options.preserveElementIdsForFiltering) !==
221
229
  this.importer.options.preserveElementIdsForFiltering) {
222
- const errMessage = "A custom importer was passed as a target but its 'preserveElementIdsForFiltering' option is out of sync with the transformer's option.";
223
- throw new Error(errMessage);
230
+ core_bentley_1.ITwinError.throwError({
231
+ iTwinErrorId: {
232
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
233
+ key: IModelTransformerError_1.IModelTransformerError.ImporterOptionMismatch,
234
+ },
235
+ message: "A custom importer was passed as a target but its 'preserveElementIdsForFiltering' option is out of sync with the transformer's option.",
236
+ });
224
237
  }
225
238
  if (Boolean(this._options.skipPropagateChangesToRootElements) !==
226
239
  this.importer.options.skipPropagateChangesToRootElements) {
227
- const errMessage = "A custom importer was passed as a target but its 'skipPropagateChangesToRootElements' option is out of sync with the transformer's option.";
228
- throw new Error(errMessage);
240
+ core_bentley_1.ITwinError.throwError({
241
+ iTwinErrorId: {
242
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
243
+ key: IModelTransformerError_1.IModelTransformerError.ImporterOptionMismatch,
244
+ },
245
+ message: "A custom importer was passed as a target but its 'skipPropagateChangesToRootElements' option is out of sync with the transformer's option.",
246
+ });
229
247
  }
230
248
  }
231
249
  /** Dispose any native resources associated with this IModelTransformer. */
@@ -371,7 +389,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
371
389
  const srcEcefLoc = this.sourceDb.ecefLocation;
372
390
  const targetEcefLoc = this.targetDb.ecefLocation;
373
391
  if (srcEcefLoc === undefined || targetEcefLoc === undefined) {
374
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NoGeoLocation, "Both source and target ECEF locations must be defined to calculate the transform.");
392
+ core_bentley_1.ITwinError.throwError({
393
+ iTwinErrorId: {
394
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
395
+ key: IModelTransformerError_1.IModelTransformerError.GeolocationUnavailable,
396
+ },
397
+ message: "Both source and target ECEF locations must be defined to calculate the transform.",
398
+ });
375
399
  }
376
400
  if (srcEcefLoc.getTransform().isAlmostEqual(targetEcefLoc.getTransform())) {
377
401
  core_bentley_1.Logger.logTrace(loggerCategory, "ECEF data is already aligned. No spatial transforms needed.");
@@ -380,7 +404,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
380
404
  const srcSpatialToECEF = srcEcefLoc.getTransform(); // converts relative to ECEF in relation to source
381
405
  const targetECEFToSpatial = targetEcefLoc.getTransform().inverse(); // converts ECEF to relative in relation to target
382
406
  if (!targetECEFToSpatial) {
383
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NoGeoLocation, "Failed to invert target ECEF transform.");
407
+ core_bentley_1.ITwinError.throwError({
408
+ iTwinErrorId: {
409
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
410
+ key: IModelTransformerError_1.IModelTransformerError.GeolocationUnavailable,
411
+ },
412
+ message: "Failed to invert target ECEF transform.",
413
+ });
384
414
  }
385
415
  const ecefTransform = targetECEFToSpatial.multiplyTransformTransform(srcSpatialToECEF); // chain both transforms
386
416
  return ecefTransform;
@@ -398,15 +428,33 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
398
428
  calculateTransformFromHelmertTransforms() {
399
429
  if (this.sourceDb.geographicCoordinateSystem?.horizontalCRS === undefined ||
400
430
  this.sourceDb.geographicCoordinateSystem?.verticalCRS === undefined) {
401
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Source iModel does not have a geographic coordinate system defined.");
431
+ core_bentley_1.ITwinError.throwError({
432
+ iTwinErrorId: {
433
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
434
+ key: IModelTransformerError_1.IModelTransformerError.GeographicCoordinateSystemUnavailable,
435
+ },
436
+ message: "Source iModel does not have a geographic coordinate system defined.",
437
+ });
402
438
  }
403
439
  if (this.targetDb.geographicCoordinateSystem?.horizontalCRS === undefined ||
404
440
  this.targetDb.geographicCoordinateSystem.verticalCRS === undefined) {
405
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "Target iModel does not have a geographic coordinate system defined.");
441
+ core_bentley_1.ITwinError.throwError({
442
+ iTwinErrorId: {
443
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
444
+ key: IModelTransformerError_1.IModelTransformerError.GeographicCoordinateSystemUnavailable,
445
+ },
446
+ message: "Target iModel does not have a geographic coordinate system defined.",
447
+ });
406
448
  }
407
449
  if (!this.sourceDb.geographicCoordinateSystem.horizontalCRS.equals(this.targetDb.geographicCoordinateSystem.horizontalCRS) ||
408
450
  !this.sourceDb.geographicCoordinateSystem.verticalCRS.equals(this.targetDb.geographicCoordinateSystem.verticalCRS)) {
409
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.MismatchGcs, "Source and target geographic coordinate systems must match to calculate the spatial transform.");
451
+ core_bentley_1.ITwinError.throwError({
452
+ iTwinErrorId: {
453
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
454
+ key: IModelTransformerError_1.IModelTransformerError.GeographicCoordinateSystemMismatch,
455
+ },
456
+ message: "Source and target geographic coordinate systems must match to calculate the spatial transform.",
457
+ });
410
458
  }
411
459
  if (this.sourceDb.geographicCoordinateSystem.additionalTransform ===
412
460
  this.targetDb.geographicCoordinateSystem.additionalTransform) {
@@ -418,14 +466,26 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
418
466
  const targetScale = this.targetDb.geographicCoordinateSystem.additionalTransform
419
467
  ?.helmert2DWithZOffset?.scale ?? 1;
420
468
  if (srcScale !== targetScale) {
421
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.MismatchGcs, "Spatial transform is non rigid. Source and target Helmert transforms must have the same scale to calculate a rigid spatial transform.");
469
+ core_bentley_1.ITwinError.throwError({
470
+ iTwinErrorId: {
471
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
472
+ key: IModelTransformerError_1.IModelTransformerError.GeographicCoordinateSystemMismatch,
473
+ },
474
+ message: "Spatial transform is non rigid. Source and target Helmert transforms must have the same scale to calculate a rigid spatial transform.",
475
+ });
422
476
  }
423
477
  const srcTransform = IModelTransformer.convertHelmertToTransform(this.sourceDb.geographicCoordinateSystem.additionalTransform
424
478
  ?.helmert2DWithZOffset); // moves elements to where src helmert transform would move them at render time
425
479
  const targetTransformInv = IModelTransformer.convertHelmertToTransform(this.targetDb.geographicCoordinateSystem.additionalTransform
426
480
  ?.helmert2DWithZOffset).inverse(); // negates target helmert transform that is applied at render time
427
481
  if (!targetTransformInv) {
428
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NoGeoLocation, "Failed to invert target Helmert transform.");
482
+ core_bentley_1.ITwinError.throwError({
483
+ iTwinErrorId: {
484
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
485
+ key: IModelTransformerError_1.IModelTransformerError.GeolocationUnavailable,
486
+ },
487
+ message: "Failed to invert target Helmert transform.",
488
+ });
429
489
  }
430
490
  const combinedTransform = targetTransformInv.multiplyTransformTransform(srcTransform);
431
491
  return combinedTransform;
@@ -502,12 +562,18 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
502
562
  entityReference: referenceId,
503
563
  });
504
564
  if (!referencedExistsInSource) {
505
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, [
506
- `Found a reference to an element "${referenceId}" that doesn't exist while looking for references of "${entity.id}".`,
507
- "This must have been caused by an upstream application that changed the iModel.",
508
- "You can set the IModelTransformOptions.danglingReferencesBehavior option to 'ignore' to ignore this,",
509
- `and the referenceId found on "${entity.id}" will not be carried over to corresponding target element.`,
510
- ].join("\n"));
565
+ core_bentley_1.ITwinError.throwError({
566
+ iTwinErrorId: {
567
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
568
+ key: IModelTransformerError_1.IModelTransformerError.DanglingReference,
569
+ },
570
+ message: [
571
+ `Found a reference to an element "${referenceId}" that doesn't exist while looking for references of "${entity.id}".`,
572
+ "This must have been caused by an upstream application that changed the iModel.",
573
+ "You can set the IModelTransformOptions.danglingReferencesBehavior option to 'ignore' to ignore this,",
574
+ `and the referenceId found on "${entity.id}" will not be carried over to corresponding target element.`,
575
+ ].join("\n"),
576
+ });
511
577
  }
512
578
  }
513
579
  /** Cause the specified Element and its child Elements (if applicable) to be exported from the source iModel and imported into the target iModel.
@@ -517,7 +583,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
517
583
  async processElement(sourceElementId) {
518
584
  await this.initialize();
519
585
  if (sourceElementId === core_common_1.IModel.rootSubjectId) {
520
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, "The root Subject should not be directly imported");
586
+ core_bentley_1.ITwinError.throwError({
587
+ iTwinErrorId: {
588
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
589
+ key: IModelTransformerError_1.IModelTransformerError.RootSubjectNotProcessable,
590
+ },
591
+ message: "The root Subject should not be directly imported",
592
+ });
521
593
  }
522
594
  return this.exporter.exportElement(sourceElementId);
523
595
  }
@@ -606,9 +678,21 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
606
678
  // It mimicks 4.x implementation: https://github.com/iTwin/itwinjs-core/blob/9c8b394ec3878a39764be81f928fd8b0b9115d31/core/backend/src/IModelDb.ts#L1882
607
679
  async queryElementIdByCode(iModel, code) {
608
680
  if (core_bentley_1.Id64.isInvalid(code.spec))
609
- throw new Error("Invalid CodeSpec");
681
+ core_bentley_1.ITwinError.throwError({
682
+ iTwinErrorId: {
683
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
684
+ key: IModelTransformerError_1.IModelTransformerError.InvalidCode,
685
+ },
686
+ message: "Invalid CodeSpec",
687
+ });
610
688
  if (code.value === undefined)
611
- throw new Error("Invalid Code");
689
+ core_bentley_1.ITwinError.throwError({
690
+ iTwinErrorId: {
691
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
692
+ key: IModelTransformerError_1.IModelTransformerError.InvalidCode,
693
+ },
694
+ message: "Invalid Code",
695
+ });
612
696
  const query = "SELECT ECInstanceId FROM BisCore:Element WHERE CodeSpec.Id=? AND CodeScope.Id=? AND CodeValue=?";
613
697
  const queryBinder = new core_common_1.QueryBinder()
614
698
  .bindId(1, code.spec)
@@ -678,7 +762,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
678
762
  const isValid = core_bentley_1.Id64.isValid(targetElementId);
679
763
  if (isValid && targetElementId !== sourceElement.id) {
680
764
  // Element found with different id
681
- throw new Error(`Element id(${sourceElement.id}) cannot be preserved. Found a different mapping(${targetElementId}) from source element`);
765
+ core_bentley_1.ITwinError.throwError({
766
+ iTwinErrorId: {
767
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
768
+ key: IModelTransformerError_1.IModelTransformerError.ElementIdNotPreservable,
769
+ },
770
+ message: `Element id(${sourceElement.id}) cannot be preserved. Found a different mapping(${targetElementId}) from source element`,
771
+ });
682
772
  }
683
773
  else if (isValid && targetElementId === sourceElement.id) {
684
774
  // targetElementId is valid (indicating update)
@@ -689,7 +779,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
689
779
  // if we don't find mapping for source element in target(invalid) but another element with source id exists in target
690
780
  if (sourceInTargetElemProps) {
691
781
  // Element id is already taken by another element
692
- throw new Error(`Element id(${sourceElement.id}) cannot be preserved. An unrelated element in the target already uses id: ${sourceElement.id}`);
782
+ core_bentley_1.ITwinError.throwError({
783
+ iTwinErrorId: {
784
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
785
+ key: IModelTransformerError_1.IModelTransformerError.ElementIdNotPreservable,
786
+ },
787
+ message: `Element id(${sourceElement.id}) cannot be preserved. An unrelated element in the target already uses id: ${sourceElement.id}`,
788
+ });
693
789
  }
694
790
  else {
695
791
  // Element id in target is available to be remapped
@@ -701,7 +797,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
701
797
  await this.importer.importElement(targetElementProps); // don't need to import if iModel was copied
702
798
  }
703
799
  if (targetElementProps.id === undefined) {
704
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadElement, "targetElementProps.id should be assigned by importElement");
800
+ throw new Error("targetElementProps.id should be assigned by importElement");
705
801
  }
706
802
  this.context.remapElement(sourceElement.id, targetElementProps.id);
707
803
  // the transformer does not currently 'split' or 'join' any elements, therefore, it does not
@@ -760,7 +856,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
760
856
  const targetModelProps = this.onTransformModel(sourceModel, targetModeledElementId);
761
857
  await this.importer.importModel(targetModelProps);
762
858
  if (targetModelProps.id === undefined) {
763
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadModel, "targetModelProps.id should be assigned by now");
859
+ throw new Error("targetModelProps.id should be assigned by now");
764
860
  }
765
861
  this._targetModelsImportedInCurrentTransform.add(targetModelProps.id);
766
862
  }
@@ -883,7 +979,13 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
883
979
  };
884
980
  targetModelProps.id = targetModeledElementId;
885
981
  if (targetModelProps.parentModel === undefined) {
886
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadElement, "targetElementProps must have a defined parentModel");
982
+ core_bentley_1.ITwinError.throwError({
983
+ iTwinErrorId: {
984
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
985
+ key: IModelTransformerError_1.IModelTransformerError.ParentModelRequired,
986
+ },
987
+ message: "targetElementProps must have a defined parentModel",
988
+ });
887
989
  }
888
990
  targetModelProps.parentModel = this.context.findTargetElementId(targetModelProps.parentModel);
889
991
  return targetModelProps;
@@ -992,13 +1094,15 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
992
1094
  targetRelationshipProps.sourceId = this.context.findTargetElementId(sourceRelationship.sourceId);
993
1095
  targetRelationshipProps.targetId = this.context.findTargetElementId(sourceRelationship.targetId);
994
1096
  // TODO: move to cloneRelationship in IModelCloneContext
995
- // eslint-disable-next-line @typescript-eslint/no-deprecated -- forEach deprecated in core 5.10, migration tracked separately
996
- sourceRelationship.forEach((propertyName, property) => {
1097
+ const relationshipClass = sourceRelationship.iModel.schemaContext.getSchemaItemSync(sourceRelationship.schemaItemKey, ECSchemaMetaData.RelationshipClass);
1098
+ (0, core_bentley_1.assert)(relationshipClass !== undefined, `Cannot get metadata for ${sourceRelationship.classFullName}.`);
1099
+ for (const property of relationshipClass.getPropertiesSync()) {
1100
+ const propertyName = property.name;
997
1101
  if (property.isPrimitive() && "Id" === property.extendedTypeName) {
998
1102
  targetRelationshipProps[core_common_1.ECJsNames.toJsName(propertyName)] =
999
1103
  this.context.findTargetElementId(sourceRelationship.asAny[core_common_1.ECJsNames.toJsName(propertyName)]);
1000
1104
  }
1001
- });
1105
+ }
1002
1106
  return targetRelationshipProps;
1003
1107
  }
1004
1108
  async shouldExportElementAspect(aspect) {
@@ -1280,9 +1384,21 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1280
1384
  const changeType = change.$meta?.op;
1281
1385
  const ecClassId = change.ECClassId ?? change.$meta?.fallbackClassId;
1282
1386
  if (ecClassId === undefined)
1283
- throw new Error(`ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change?.$meta?.tables}`);
1387
+ core_bentley_1.ITwinError.throwError({
1388
+ iTwinErrorId: {
1389
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1390
+ key: IModelTransformerError_1.IModelTransformerError.ChangedInstanceMetadataMissing,
1391
+ },
1392
+ message: `ECClassId was not found for id: ${change.ECInstanceId}! Table is : ${change?.$meta?.tables}`,
1393
+ });
1284
1394
  if (changeType === undefined)
1285
- throw new Error(`ChangeType was undefined for id: ${change.ECInstanceId}.`);
1395
+ core_bentley_1.ITwinError.throwError({
1396
+ iTwinErrorId: {
1397
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1398
+ key: IModelTransformerError_1.IModelTransformerError.ChangedInstanceMetadataMissing,
1399
+ },
1400
+ message: `ChangeType was undefined for id: ${change.ECInstanceId}.`,
1401
+ });
1286
1402
  if (changeType !== "Deleted" ||
1287
1403
  relationshipECClassIdsToSkip.has(ecClassId))
1288
1404
  continue;
@@ -1405,7 +1521,7 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1405
1521
  if (deletionNotInTarget)
1406
1522
  return;
1407
1523
  if (targetId === undefined) {
1408
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadElement, "targetId should be acquired from source id or element provenance");
1524
+ throw new Error("targetId should be acquired from source id or element provenance");
1409
1525
  }
1410
1526
  this.context.remapElement(changedInstanceId, targetId);
1411
1527
  // If an entity insert and an entity delete both point to the same entity in target iModel, that means that entity was recreated.
@@ -1448,13 +1564,19 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1448
1564
  ?.ignoreMissingChangesetsInSynchronizations &&
1449
1565
  startChangesetIndex !== syncVersion.index + 1 &&
1450
1566
  syncVersion.index !== -1) {
1451
- throw Error(`synchronization is ${missingChangesets ? "missing changesets" : ""},` +
1452
- " startChangesetId should be" +
1453
- " exactly the first changeset *after* the previous synchronization to not miss data." +
1454
- ` You specified '${startChangesetIndexOrId}' which is changeset #${startChangesetIndex}` +
1455
- ` but the previous synchronization for this targetScopeElem ${syncVersion.id}'` +
1456
- ` which is changeset #${syncVersion.index}. The transformer expected` +
1457
- ` #${syncVersion.index + 1}.`);
1567
+ core_bentley_1.ITwinError.throwError({
1568
+ iTwinErrorId: {
1569
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1570
+ key: IModelTransformerError_1.IModelTransformerError.SynchronizationRangeInvalid,
1571
+ },
1572
+ message: `synchronization is ${missingChangesets ? "missing changesets" : ""},` +
1573
+ " startChangesetId should be" +
1574
+ " exactly the first changeset *after* the previous synchronization to not miss data." +
1575
+ ` You specified '${startChangesetIndexOrId}' which is changeset #${startChangesetIndex}` +
1576
+ ` but the previous synchronization for this targetScopeElem ${syncVersion.id}'` +
1577
+ ` which is changeset #${syncVersion.index}. The transformer expected` +
1578
+ ` #${syncVersion.index + 1}.`,
1579
+ });
1458
1580
  }
1459
1581
  const changesetsToSkip = await this._provenanceManager.getChangesetsToSkip();
1460
1582
  core_bentley_1.Logger.logTrace(loggerCategory, `changesets to skip: ${changesetsToSkip}`);
@@ -1478,10 +1600,22 @@ class IModelTransformer extends IModelExporter_1.IModelExportHandler {
1478
1600
  /** Asserts that the EditTxn is active before any write operations. */
1479
1601
  assertEditTxnActive() {
1480
1602
  if (!this._targetEditTxn.isActive) {
1481
- throw new Error("The target EditTxn must be started before calling process(). Call targetEditTxn.start() before invoking the transformer.");
1603
+ core_bentley_1.ITwinError.throwError({
1604
+ iTwinErrorId: {
1605
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1606
+ key: IModelTransformerError_1.IModelTransformerError.EditTxnNotActive,
1607
+ },
1608
+ message: "The target EditTxn must be started before calling process(). Call targetEditTxn.start() before invoking the transformer.",
1609
+ });
1482
1610
  }
1483
1611
  if (this._sourceEditTxn && !this._sourceEditTxn.isActive) {
1484
- throw new Error("The source EditTxn was provided but is not active. Call sourceEditTxn.start() before invoking the transformer.");
1612
+ core_bentley_1.ITwinError.throwError({
1613
+ iTwinErrorId: {
1614
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1615
+ key: IModelTransformerError_1.IModelTransformerError.EditTxnNotActive,
1616
+ },
1617
+ message: "The source EditTxn was provided but is not active. Call sourceEditTxn.start() before invoking the transformer.",
1618
+ });
1485
1619
  }
1486
1620
  }
1487
1621
  /**
@@ -1673,7 +1807,13 @@ class TemplateModelCloner extends IModelTransformer {
1673
1807
  // TODO: consider going through all definition elements at once and remapping them to themselves
1674
1808
  if (!core_backend_1.EntityReferences.isValid(await this.context.findTargetEntityId(referenceId))) {
1675
1809
  if (this.context.isBetweenIModels) {
1676
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `Remapping for source dependency ${referenceId} not found for target iModel`);
1810
+ core_bentley_1.ITwinError.throwError({
1811
+ iTwinErrorId: {
1812
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1813
+ key: IModelTransformerError_1.IModelTransformerError.DependencyMappingMissing,
1814
+ },
1815
+ message: `Remapping for source dependency ${referenceId} not found for target iModel`,
1816
+ });
1677
1817
  }
1678
1818
  else {
1679
1819
  const definitionElement = this.sourceDb.elements.tryGetElement(referenceId, core_backend_1.DefinitionElement);
@@ -1682,7 +1822,13 @@ class TemplateModelCloner extends IModelTransformer {
1682
1822
  this.context.remapElement(referenceId, referenceId); // when in the same iModel, can use existing DefinitionElements without remapping
1683
1823
  }
1684
1824
  else {
1685
- throw new core_common_1.IModelError(core_bentley_1.IModelStatus.BadRequest, `Remapping for dependency ${referenceId} not found`);
1825
+ core_bentley_1.ITwinError.throwError({
1826
+ iTwinErrorId: {
1827
+ scope: IModelTransformerError_1.IModelTransformerErrorScope,
1828
+ key: IModelTransformerError_1.IModelTransformerError.DependencyMappingMissing,
1829
+ },
1830
+ message: `Remapping for dependency ${referenceId} not found`,
1831
+ });
1686
1832
  }
1687
1833
  }
1688
1834
  }