chore(orchestration): serialize error (#6967)
This commit is contained in:
1 parent
232322d035
commit
d333db0842
9 files changed
+87
-35
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/orchestration": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Serialize orchestrator error
|
||||||
@@ -326,7 +326,7 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "find-one-or-any-region",
|
action: "find-one-or-any-region",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error("No regions found"),
|
error: expect.objectContaining({ message: "No regions found" }),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -417,9 +417,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "confirm-inventory-step",
|
action: "confirm-inventory-step",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
"Some variant does not have the required inventory"
|
message: "Some variant does not have the required inventory",
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -441,9 +441,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "find-sales-channel",
|
action: "find-sales-channel",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Unable to assign cart to disabled Sales Channel: Webshop`
|
message: `Unable to assign cart to disabled Sales Channel: Webshop`,
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -471,7 +471,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Failed to create cart`),
|
error: expect.objectContaining({
|
||||||
|
message: `Failed to create cart`,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -508,7 +510,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Failed to create cart`),
|
error: expect.objectContaining({
|
||||||
|
message: `Failed to create cart`,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -705,9 +709,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "get-variant-price-sets",
|
action: "get-variant-price-sets",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Variants with IDs ${product.variants[0].id} do not have a price`
|
message: `Variants with IDs ${product.variants[0].id} do not have a price`,
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -734,7 +738,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "validate-variants-exist",
|
action: "validate-variants-exist",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Variants with IDs prva_foo do not exist`),
|
error: expect.objectContaining({
|
||||||
|
message: `Variants with IDs prva_foo do not exist`,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -975,7 +981,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Failed to update something after line items`),
|
error: expect.objectContaining({
|
||||||
|
message: `Failed to update something after line items`,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1064,9 +1072,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Failed to do something after deleting line items`
|
message: `Failed to do something after deleting line items`,
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1178,9 +1186,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Failed to do something after linking cart and payment collection`
|
message: `Failed to do something after linking cart and payment collection`,
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1353,9 +1361,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Failed to do something after updating payment collections`
|
message: `Failed to do something after updating payment collections`,
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1807,9 +1815,9 @@ medusaIntegrationTestRunner({
|
|||||||
expect(errors).toEqual([
|
expect(errors).toEqual([
|
||||||
{
|
{
|
||||||
action: "get-shipping-option-price-sets",
|
action: "get-shipping-option-price-sets",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Shipping options with IDs ${shippingOption.id} do not have a price`
|
message: `Shipping options with IDs ${shippingOption.id} do not have a price`,
|
||||||
),
|
}),
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ medusaIntegrationTestRunner({
|
|||||||
{
|
{
|
||||||
action: "throw",
|
action: "throw",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(
|
error: expect.objectContaining({
|
||||||
`Failed to do something after creating payment sessions`
|
message: `Failed to do something after creating payment sessions`,
|
||||||
),
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ describe("CreateInventoryItem workflow", function () {
|
|||||||
{
|
{
|
||||||
action: "fail_step",
|
action: "fail_step",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Failed`),
|
error: expect.objectContaining({ message: `Failed` }),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ describe.skip("CreateProduct workflow", function () {
|
|||||||
{
|
{
|
||||||
action: "fail_step",
|
action: "fail_step",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Failed to create products`),
|
error: expect.objectContaining({
|
||||||
|
message: `Failed to create products`,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { WorkflowTypes } from "@medusajs/types"
|
|
||||||
import {
|
import {
|
||||||
Handlers,
|
Handlers,
|
||||||
updateProducts,
|
updateProducts,
|
||||||
UpdateProductsActions,
|
UpdateProductsActions,
|
||||||
} from "@medusajs/core-flows"
|
} from "@medusajs/core-flows"
|
||||||
|
import { WorkflowTypes } from "@medusajs/types"
|
||||||
import { pipe } from "@medusajs/workflows-sdk"
|
import { pipe } from "@medusajs/workflows-sdk"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|
||||||
@@ -86,7 +86,9 @@ describe.skip("UpdateProduct workflow", function () {
|
|||||||
{
|
{
|
||||||
action: "fail_step",
|
action: "fail_step",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error(`Failed to update products`),
|
error: expect.objectContaining({
|
||||||
|
message: `Failed to update products`,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -45,3 +45,30 @@ export class TransactionTimeoutError extends Error {
|
|||||||
this.name = "TransactionTimeoutError"
|
this.name = "TransactionTimeoutError"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function serializeError(error) {
|
||||||
|
const serialized = {
|
||||||
|
message: error.message,
|
||||||
|
name: error.name,
|
||||||
|
stack: error.stack,
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.getOwnPropertyNames(error).forEach((key) => {
|
||||||
|
// eslint-disable-next-line no-prototype-builtins
|
||||||
|
if (!serialized.hasOwnProperty(key)) {
|
||||||
|
serialized[key] = error[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return serialized
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isErrorLike(value) {
|
||||||
|
return (
|
||||||
|
!!value &&
|
||||||
|
typeof value === "object" &&
|
||||||
|
"name" in value &&
|
||||||
|
"message" in value &&
|
||||||
|
"stack" in value
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -16,7 +16,9 @@ import {
|
|||||||
import { MedusaError, promiseAll, TransactionStepState } from "@medusajs/utils"
|
import { MedusaError, promiseAll, TransactionStepState } from "@medusajs/utils"
|
||||||
import { EventEmitter } from "events"
|
import { EventEmitter } from "events"
|
||||||
import {
|
import {
|
||||||
|
isErrorLike,
|
||||||
PermanentStepFailureError,
|
PermanentStepFailureError,
|
||||||
|
serializeError,
|
||||||
TransactionStepTimeoutError,
|
TransactionStepTimeoutError,
|
||||||
TransactionTimeoutError,
|
TransactionTimeoutError,
|
||||||
} from "./errors"
|
} from "./errors"
|
||||||
@@ -479,6 +481,10 @@ export class TransactionOrchestrator extends EventEmitter {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
step.failures++
|
step.failures++
|
||||||
|
|
||||||
|
if (isErrorLike(error)) {
|
||||||
|
error = serializeError(error)
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isTimeout &&
|
!isTimeout &&
|
||||||
step.getStates().status !== TransactionStepStatus.PERMANENT_FAILURE
|
step.getStates().status !== TransactionStepStatus.PERMANENT_FAILURE
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createStep } from "../create-step"
|
import { createStep } from "../create-step"
|
||||||
import { StepResponse } from "../helpers"
|
|
||||||
import { createWorkflow } from "../create-workflow"
|
import { createWorkflow } from "../create-workflow"
|
||||||
|
import { StepResponse } from "../helpers"
|
||||||
import { transform } from "../transform"
|
import { transform } from "../transform"
|
||||||
|
|
||||||
describe("Workflow composer", () => {
|
describe("Workflow composer", () => {
|
||||||
@@ -31,7 +31,9 @@ describe("Workflow composer", () => {
|
|||||||
{
|
{
|
||||||
action: "step2",
|
action: "step2",
|
||||||
handlerType: "invoke",
|
handlerType: "invoke",
|
||||||
error: new Error("step2 failed"),
|
error: expect.objectContaining({
|
||||||
|
message: "step2 failed",
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
message: "Cannot read properties of undefined (reading 'result')",
|
message: "Cannot read properties of undefined (reading 'result')",
|
||||||
|
|||||||
Reference in new issue
Block a user