Gestión de errores en módulos de servidor
This commit is contained in:
parent
55983f0295
commit
2c84dc26bd
@ -1,2 +1,2 @@
|
||||
export * from "./customer-invoice-id-already-exits-error";
|
||||
export * from "./invalid-proforma-status-error";
|
||||
export * from "./proforma-cannot-be-converted-to-invoice-error";
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
import { DomainError } from "@repo/rdx-ddd";
|
||||
|
||||
export class InvalidProformaStatusError extends DomainError {
|
||||
constructor(id: string, options?: ErrorOptions) {
|
||||
super(`Error. Proforma with id '${id}' has invalid status.`, options);
|
||||
this.name = "InvalidProformaStatusError";
|
||||
}
|
||||
}
|
||||
|
||||
export const isInvalidProformaStatusError = (e: unknown): e is InvalidProformaStatusError =>
|
||||
e instanceof InvalidProformaStatusError;
|
||||
@ -0,0 +1,33 @@
|
||||
import { DomainError } from "@repo/rdx-ddd";
|
||||
|
||||
/**
|
||||
* Error de dominio que indica que una Proforma no puede convertirse a Factura (issue).
|
||||
*
|
||||
* @remarks
|
||||
* - Se lanza cuando el flujo de emisión (issue) desde una Proforma no es válido
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class ProformaCannotBeConvertedToInvoiceError extends DomainError {
|
||||
/**
|
||||
* Crea una instancia del error con el identificador de la Proforma.
|
||||
*
|
||||
* @param id - Identificador de la Proforma.
|
||||
* @param options - Opciones nativas de Error (puedes pasar `cause`).
|
||||
*/
|
||||
constructor(id: string, options?: ErrorOptions) {
|
||||
super(`Error. Proforma with id '${id}' cannot be converted to an Invoice.`, options);
|
||||
this.name = "ProformaCannotBeConvertedToInvoiceError";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* *Type guard* para `ProformaCannotBeConvertedToInvoiceError`.
|
||||
*
|
||||
* @param e - Error desconocido
|
||||
* @returns `true` si `e` es `ProformaCannotBeConvertedToInvoiceError`
|
||||
*/
|
||||
export const isProformaCannotBeConvertedToInvoiceError = (
|
||||
e: unknown
|
||||
): e is ProformaCannotBeConvertedToInvoiceError =>
|
||||
e instanceof ProformaCannotBeConvertedToInvoiceError;
|
||||
@ -1,11 +1,14 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
|
||||
import { CreateCustomerInvoiceRequestDTO } from "../../../../common/dto";
|
||||
import { CreateCustomerInvoiceUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class CreateCustomerInvoiceController extends ExpressController {
|
||||
public constructor(private readonly useCase: CreateCustomerInvoiceUseCase) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { DeleteCustomerInvoiceUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class DeleteCustomerInvoiceController extends ExpressController {
|
||||
public constructor(
|
||||
@ -7,6 +8,8 @@ export class DeleteCustomerInvoiceController extends ExpressController {
|
||||
/* private readonly presenter: any */
|
||||
) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { GetCustomerInvoiceUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class GetCustomerInvoiceController extends ExpressController {
|
||||
public constructor(private readonly useCase: GetCustomerInvoiceUseCase) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { IssueCustomerInvoiceUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class IssueCustomerInvoiceController extends ExpressController {
|
||||
public constructor(private readonly useCase: IssueCustomerInvoiceUseCase) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { ListCustomerInvoicesUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class ListCustomerInvoicesController extends ExpressController {
|
||||
public constructor(private readonly useCase: ListCustomerInvoicesUseCase) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { ReportCustomerInvoiceUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class ReportCustomerInvoiceController extends ExpressController {
|
||||
public constructor(private readonly useCase: ReportCustomerInvoiceUseCase) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { UpdateCustomerInvoiceByIdRequestDTO } from "../../../../common/dto";
|
||||
import { UpdateCustomerInvoiceUseCase } from "../../../application";
|
||||
import { customerInvoicesApiErrorMapper } from "../customer-invoices-api-error-mapper";
|
||||
|
||||
export class UpdateCustomerInvoiceController extends ExpressController {
|
||||
public constructor(private readonly useCase: UpdateCustomerInvoiceUseCase) {
|
||||
super();
|
||||
this.errorMapper = customerInvoicesApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
// Ejemplo: regla específica para Billing → InvoiceIdAlreadyExistsError
|
||||
// (si defines un error más ubicuo dentro del BC con su propia clase)
|
||||
|
||||
import { ApiErrorMapper, ConflictApiError, ErrorToApiRule } from "@erp/core/api";
|
||||
import {
|
||||
ApiErrorMapper,
|
||||
ConflictApiError,
|
||||
ErrorToApiRule,
|
||||
ValidationApiError,
|
||||
} from "@erp/core/api";
|
||||
import {
|
||||
CustomerInvoiceIdAlreadyExistsError,
|
||||
isCustomerInvoiceIdAlreadyExistsError,
|
||||
isProformaCannotBeConvertedToInvoiceError,
|
||||
ProformaCannotBeConvertedToInvoiceError,
|
||||
} from "../../domain";
|
||||
|
||||
// Crea una regla específica (prioridad alta para sobreescribir mensajes)
|
||||
@ -18,6 +25,17 @@ const invoiceDuplicateRule: ErrorToApiRule = {
|
||||
),
|
||||
};
|
||||
|
||||
const proformaConversionRule: ErrorToApiRule = {
|
||||
priority: 120,
|
||||
matches: (e) => isProformaCannotBeConvertedToInvoiceError(e),
|
||||
build: (e) =>
|
||||
new ValidationApiError(
|
||||
(e as ProformaCannotBeConvertedToInvoiceError).message ||
|
||||
"Proforma cannot be converted to an Invoice."
|
||||
),
|
||||
};
|
||||
|
||||
// Cómo aplicarla: crea una nueva instancia del mapper con la regla extra
|
||||
export const customerInvoicesApiErrorMapper: ApiErrorMapper =
|
||||
ApiErrorMapper.default().register(invoiceDuplicateRule);
|
||||
export const customerInvoicesApiErrorMapper: ApiErrorMapper = ApiErrorMapper.default()
|
||||
.register(invoiceDuplicateRule)
|
||||
.register(proformaConversionRule);
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { CreateCustomerRequestDTO } from "../../../../common/dto";
|
||||
import { CreateCustomerUseCase } from "../../../application";
|
||||
import { customersApiErrorMapper } from "../customer-api-error-mapper";
|
||||
|
||||
export class CreateCustomerController extends ExpressController {
|
||||
public constructor(private readonly useCase: CreateCustomerUseCase) {
|
||||
super();
|
||||
this.errorMapper = customersApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { DeleteCustomerUseCase } from "../../../application";
|
||||
import { customersApiErrorMapper } from "../customer-api-error-mapper";
|
||||
|
||||
export class DeleteCustomerController extends ExpressController {
|
||||
public constructor(private readonly useCase: DeleteCustomerUseCase) {
|
||||
super();
|
||||
this.errorMapper = customersApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { GetCustomerUseCase } from "../../../application";
|
||||
import { customersApiErrorMapper } from "../customer-api-error-mapper";
|
||||
|
||||
export class GetCustomerController extends ExpressController {
|
||||
public constructor(private readonly useCase: GetCustomerUseCase) {
|
||||
super();
|
||||
this.errorMapper = customersApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { Criteria } from "@repo/rdx-criteria/server";
|
||||
import { ListCustomersUseCase } from "../../../application";
|
||||
import { customersApiErrorMapper } from "../customer-api-error-mapper";
|
||||
|
||||
export class ListCustomersController extends ExpressController {
|
||||
public constructor(private readonly listCustomers: ListCustomersUseCase) {
|
||||
super();
|
||||
this.errorMapper = customersApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { authGuard, ExpressController, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
|
||||
import { UpdateCustomerByIdRequestDTO } from "../../../../common/dto";
|
||||
import { UpdateCustomerUseCase } from "../../../application";
|
||||
import { customersApiErrorMapper } from "../customer-api-error-mapper";
|
||||
|
||||
export class UpdateCustomerController extends ExpressController {
|
||||
public constructor(private readonly useCase: UpdateCustomerUseCase) {
|
||||
super();
|
||||
this.errorMapper = customersApiErrorMapper;
|
||||
|
||||
// 🔐 Reutiliza guards de auth/tenant y prohíbe 'companyId' en query
|
||||
this.registerGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ApiErrorMapper, ConflictApiError, ErrorToApiRule } from "@erp/core/api";
|
||||
import { ApiErrorMapper, ErrorToApiRule, NotFoundApiError } from "@erp/core/api";
|
||||
import { CustomerNotFoundError, isCustomerNotFoundError } from "../../domain";
|
||||
|
||||
// Crea una regla específica (prioridad alta para sobreescribir mensajes)
|
||||
@ -6,7 +6,7 @@ const customerNotFoundRule: ErrorToApiRule = {
|
||||
priority: 120,
|
||||
matches: (e) => isCustomerNotFoundError(e),
|
||||
build: (e) =>
|
||||
new ConflictApiError(
|
||||
new NotFoundApiError(
|
||||
(e as CustomerNotFoundError).message || "Customer with the provided id not exists."
|
||||
),
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user