feat: Normalize known DB errors to a MedusaError when possible (#6922)

Before we would swallow the error and return a generic error to the user. This will provide more information to the caller if it is one of the known errors.
This commit is contained in:
Stevche Radevski authored and GitHub committed 2024-04-04 19:12:59 +00:00
1 parent e944a627f0
commit 20e8df914e
14 files changed
+282 -169

No files matched your search

@@ -711,7 +711,7 @@ moduleIntegrationTestRunner({
],
})
).rejects.toThrowError(
/You are trying to create a Tax Rate Rule for a reference that already exists. Tax Rate id: .*?, reference id: product_id_1./
/Tax rate rule with tax_rate_id: .*?, reference_id: product_id_1 already exists./
)
const rate = await service.create({
@@ -729,7 +729,7 @@ moduleIntegrationTestRunner({
reference_id: "product_id_1",
})
).rejects.toThrowError(
/You are trying to create a Tax Rate Rule for a reference that already exists. Tax Rate id: .*?, reference id: product_id_1./
/Tax rate rule with tax_rate_id: .*?, reference_id: product_id_1 already exists./
)
})
@@ -764,7 +764,7 @@ moduleIntegrationTestRunner({
province_code: "QC",
})
).rejects.toThrowError(
"You are trying to create a Tax Region for (country_code: ca, province_code: qc) but one already exists."
"Tax region with country_code: ca, province_code: qc already exists."
)
})
@@ -797,7 +797,7 @@ moduleIntegrationTestRunner({
is_default: true,
})
).rejects.toThrowError(
/You are trying to create a default tax rate for region: .*? which already has a default tax rate. Unset the current default rate and try again./
/Tax rate with tax_region_id: .*? already exists./
)
})
@@ -21,9 +21,6 @@ import {
} from "@medusajs/utils"
import { TaxProvider, TaxRate, TaxRateRule, TaxRegion } from "@models"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import { singleDefaultRegionIndexName } from "../models/tax-rate"
import { uniqueRateReferenceIndexName } from "../models/tax-rate-rule"
import { countryCodeProvinceIndexName } from "../models/tax-region"
type InjectedDependencies = {
baseRepository: DAL.RepositoryService
@@ -106,11 +103,7 @@ export default class TaxModuleService<
@MedusaContext() sharedContext: Context = {}
): Promise<TaxTypes.TaxRateDTO[] | TaxTypes.TaxRateDTO> {
const input = Array.isArray(data) ? data : [data]
const rates = await this.create_(input, sharedContext).catch((err) => {
this.handleCreateError(err)
this.handleCreateRulesError(err)
throw err
})
const rates = await this.create_(input, sharedContext)
return Array.isArray(data) ? rates : rates[0]
}
@@ -182,13 +175,7 @@ export default class TaxModuleService<
data: TaxTypes.UpdateTaxRateDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<TaxTypes.TaxRateDTO | TaxTypes.TaxRateDTO[]> {
const rates = await this.update_(selector, data, sharedContext).catch(
(err) => {
this.handleCreateError(err)
this.handleCreateRulesError(err)
throw err
}
)
const rates = await this.update_(selector, data, sharedContext)
const serialized = await this.baseRepository_.serialize<
TaxTypes.TaxRateDTO[]
>(rates, { populate: true })
@@ -322,12 +309,7 @@ export default class TaxModuleService<
@MedusaContext() sharedContext: Context = {}
) {
const input = Array.isArray(data) ? data : [data]
const result = await this.createTaxRegions_(input, sharedContext).catch(
(err) => {
this.handleCreateRegionsError(err)
throw err
}
)
const result = await this.createTaxRegions_(input, sharedContext)
return Array.isArray(data) ? result : result[0]
}
@@ -382,12 +364,7 @@ export default class TaxModuleService<
@MedusaContext() sharedContext: Context = {}
) {
const input = Array.isArray(data) ? data : [data]
const result = await this.createTaxRateRules_(input, sharedContext).catch(
(err) => {
this.handleCreateRulesError(err)
throw err
}
)
const result = await this.createTaxRateRules_(input, sharedContext)
return Array.isArray(data) ? result : result[0]
}
@@ -748,49 +725,6 @@ export default class TaxModuleService<
return code.toLowerCase()
}
private handleCreateRegionsError(err: any) {
if (err.constraint === countryCodeProvinceIndexName) {
const [countryCode, provinceCode] = err.detail
.split("=")[1]
.match(/\(([^)]+)\)/)[1]
.split(",")
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You are trying to create a Tax Region for (country_code: ${countryCode.trim()}, province_code: ${provinceCode.trim()}) but one already exists.`
)
}
}
private handleCreateError(err: any) {
if (err.constraint === singleDefaultRegionIndexName) {
// err.detail = Key (tax_region_id)=(txreg_01HQX5E8GEH36ZHJWFYDAFY67P) already exists.
const regionId = err.detail.split("=")[1].match(/\(([^)]+)\)/)[1]
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You are trying to create a default tax rate for region: ${regionId} which already has a default tax rate. Unset the current default rate and try again.`
)
}
}
private handleCreateRulesError(err: any) {
if (err.constraint === uniqueRateReferenceIndexName) {
// err.detail == "Key (tax_rate_id, reference_id)=(txr_01HQWRXTC0JK0F02D977WRR45T, product_id_1) already exists."
// We want to extract the ids from the detail string
// i.e. txr_01HQWRXTC0JK0F02D977WRR45T and product_id_1
const [taxRateId, referenceId] = err.detail
.split("=")[1]
.match(/\(([^)]+)\)/)[1]
.split(",")
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`You are trying to create a Tax Rate Rule for a reference that already exists. Tax Rate id: ${taxRateId.trim()}, reference id: ${referenceId.trim()}.`
)
}
}
// @InjectTransactionManager("baseRepository_")
// async createProvidersOnLoad(@MedusaContext() sharedContext: Context = {}) {
// const providersToLoad = this.container_["tax_providers"] as ITaxProvider[]