MapPersistenceErrors
MapPersistenceErrors<
TArgs,TEntity,TConstraint,TThis>(options): <TResult>(_target,_key,descriptor) =>void
Defined in: packages/ddd-core/persistence/decorators/map-persistence-errors.decorator.ts:70
Method decorator that intercepts persistence failures from the wrapped method and translates identifiable database unique constraint violations into domain exceptions.
Error Matching Mechanics
Section titled “Error Matching Mechanics”- Unique violations: the persistence dialect (IPersistenceDialect) names the
violated constraint by the entity property it covers;
unique[key]builds the domain error. The dialect comes fromoptions.dialect, else from setPersistenceDialect. A method that declaresuniquewith no dialect available throws aTypeErrorbefore it runs, so a violation never escapes as a raw driver error. - Residual translation: Any error not matching a configured constraint is passed to the
optional
otherwisetranslator, which is the declarative place to convert driver/network failures into the neutral TransientOperationError retry signal. - Passthrough: Without
otherwise— or whenotherwisereturns the error unchanged — the error is rethrown with its original identity, class, and stack trace completely preserved.
Use otherwise for application-level translation of unmatched driver or
network failures. Keep persistence translation in this decorator so the
lifecycle order relative to @AcknowledgePersisted and @Cache remains
explicit in the decorator stack.
Canonical Decorator Ordering
Section titled “Canonical Decorator Ordering”Always stack decorators in this outermost-to-innermost order:
@Cache(...)— Best-effort cache synchronization after acknowledgment.@AcknowledgePersisted(...)— Acknowledges version baseline on successful write.@MapPersistenceErrors(...)— Translates low-level DB driver errors to domain exceptions.
Type Parameters
Section titled “Type Parameters”TArgs extends unknown[]
TEntity
Section titled “TEntity”TEntity
TConstraint
Section titled “TConstraint”TConstraint extends string = never
TThis = unknown
Parameters
Section titled “Parameters”options
Section titled “options”The entity extractor, the unique errors, an optional dialect
overriding the registered one (for a repository on another store), and an
optional otherwise translator.
dialect?
Section titled “dialect?”entity
Section titled “entity”(args) => TEntity
otherwise?
Section titled “otherwise?”(this, error, entity) => unknown
Optional translator applied to any error that did not match a unique constraint mapping. Return the error unchanged to preserve its identity, or return a replacement to express it in application terms.
The canonical use is transient-failure classification with
mapPersistenceError, so that retry policies consume
TransientOperationError rather than driver codes:
otherwise: (error, user) => mapPersistenceError(error, `deleting User ${user.id}`),Deliberate domain errors thrown inside the method (ConcurrencyConflictError,
EntityNotFoundException) also pass through this hook. mapPersistenceError
returns non-transient errors unchanged, so no explicit re-throw guard is needed.
Written as a method, it runs with this bound to the repository instance
(typed by TThis), for a message that names instance state.
unique?
Section titled “unique?”UniqueErrors<TEntity, TConstraint>
Returns
Section titled “Returns”<TResult>(_target, _key, descriptor) => void
Example
Section titled “Example”Mapping unique constraints in a create repository
@Injectable()export class CreateUserCommandRepository extends CommandRepository<User, UserSnapshot> { @Cache<User, UserSnapshot>((u) => `users:${u.id}`, null, (u) => [`users:email:${u.email}`]) @AcknowledgePersisted<[User]>({ entity: ([user]) => user }) @MapPersistenceErrors<[User], User>({ entity: ([user]) => user, unique: { email: (user) => new UniqueEmailException(user) }, }) async save(user: User): Promise<UserSnapshot> { const created = this.store.em.create(User, user); this.store.em.persist(created); await this.store.em.flush(); return created.toJSON(); }}