From 79a50a7a9f68f87eb5558cc0043e105496139335 Mon Sep 17 00:00:00 2001 From: Philipp Ossler Date: Fri, 15 Dec 2023 06:29:44 +0100 Subject: [PATCH 1/4] feat(sdk): Update SDK to version 3 --- sdk/spacetraders.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/spacetraders.json b/sdk/spacetraders.json index 6948a98..01834dd 100644 --- a/sdk/spacetraders.json +++ b/sdk/spacetraders.json @@ -6,7 +6,7 @@ "icon": { "contents": "data:image/png;base64,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" }, - "version": 2, + "version": 3, "appliesTo": [ "bpmn:Task" ], From f89163d681fca4c36fe1574fca73bd98bdb6aeac Mon Sep 17 00:00:00 2001 From: Philipp Ossler Date: Fri, 15 Dec 2023 06:27:45 +0100 Subject: [PATCH 2/4] feat(sdk): API retries - Allows to configure the number of retries and the retry backoff - By default, 10 retries with 1 second delay --- sdk/spacetraders.json | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sdk/spacetraders.json b/sdk/spacetraders.json index 01834dd..fbf86ee 100644 --- a/sdk/spacetraders.json +++ b/sdk/spacetraders.json @@ -30,6 +30,10 @@ "id": "responseMapping", "label": "Response Mapping" }, + { + "id": "retries", + "label": "API Retries" + }, { "id": "modificationWarning", "label": "Generated (DO NOT MODIFY)" @@ -6955,6 +6959,32 @@ "equals": "register" }, "optional": true + }, + { + "id": "retryCount", + "label": "Retries", + "description": "Number of retries", + "value": "10", + "feel": "optional", + "group": "retries", + "binding": { + "property": "retries", + "type": "zeebe:taskDefinition" + }, + "type": "String" + }, + { + "id": "retryBackoff", + "label": "Retry backoff", + "description": "ISO-8601 duration to wait between retries", + "value": "PT1S", + "feel": "optional", + "group": "retries", + "binding": { + "key": "retryBackoff", + "type": "zeebe:taskHeader" + }, + "type": "String" } ] } \ No newline at end of file From 6a18285533609f8a1f33f7cc363216b63eb51a8e Mon Sep 17 00:00:00 2001 From: Philipp Ossler Date: Fri, 15 Dec 2023 14:29:39 +0100 Subject: [PATCH 3/4] feat(sdk): Error handling - Allows to define an error expression - By default, it throws a BPMN error if the error has a status code 400. The error code of the BPMN error is the name to the SpaceTrader's error code based on the documentation. - A custom handling can override the default --- assets/error_codes.txt | 95 ++++++++++++++++++++++++++++++++++++++++++ sdk/spacetraders.json | 62 ++++++++++++++++++++++++++- 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 assets/error_codes.txt diff --git a/assets/error_codes.txt b/assets/error_codes.txt new file mode 100644 index 0000000..41d51f3 --- /dev/null +++ b/assets/error_codes.txt @@ -0,0 +1,95 @@ +const cooldownConflictError = 4000 +const waypointNoAccessError = 4001 +const tokenEmptyError = 4100 +const tokenMissingSubjectError = 4101 +const tokenInvalidSubjectError = 4102 +const missingTokenRequestError = 4103 +const invalidTokenRequestError = 4104 +const invalidTokenSubjectError = 4105 +const accountNotExistsError = 4106 +const agentNotExistsError = 4107 +const accountHasNoAgentError = 4108 +const registerAgentExistsError = 4109 +const registerAgentSymbolReservedError = 4110 +const registerAgentConflictSymbolError = 4111 +const navigateInTransitError = 4200 +const navigateInvalidDestinationError = 4201 +const navigateOutsideSystemError = 4202 +const navigateInsufficientFuelError = 4203 +const navigateSameDestinationError = 4204 +const shipExtractInvalidWaypointError = 4205 +const shipExtractPermissionError = 4206 +const shipJumpNoSystemError = 4207 +const shipJumpSameSystemError = 4208 +const shipJumpMissingModuleError = 4210 +const shipJumpNoValidWaypointError = 4211 +const shipJumpMissingAntimatterError = 4212 +const shipInTransitError = 4214 +const shipMissingSensorArraysError = 4215 +const purchaseShipCreditsError = 4216 +const shipCargoExceedsLimitError = 4217 +const shipCargoMissingError = 4218 +const shipCargoUnitCountError = 4219 +const shipSurveyVerificationError = 4220 +const shipSurveyExpirationError = 4221 +const shipSurveyWaypointTypeError = 4222 +const shipSurveyOrbitError = 4223 +const shipSurveyExhaustedError = 4224 +const shipRefuelDockedError = 4225 +const shipRefuelInvalidWaypointError = 4226 +const shipMissingMountsError = 4227 +const shipCargoFullError = 4228 +const shipJumpFromGateToGateError = 4229 +const waypointChartedError = 4230 +const shipTransferShipNotFound = 4231 +const shipTransferAgentConflict = 4232 +const shipTransferSameShipConflict = 4233 +const shipTransferLocationConflict = 4234 +const warpInsideSystemError = 4235 +const shipNotInOrbitError = 4236 +const shipInvalidRefineryGoodError = 4237 +const shipInvalidRefineryTypeError = 4238 +const shipMissingRefineryError = 4239 +const shipMissingSurveyorError = 4240 +const shipMissingWarpDriveError = 4241 +const shipMissingMineralProcessorError = 4242 +const shipMissingMiningLasersError = 4243 +const shipNotDockedError = 4244 +const purchaseShipNotPresentError = 4245 +const shipMountNoShipyardError = 4246 +const shipMissingMountError = 4247 +const shipMountInsufficientCreditsError = 4248 +const shipMissingPowerError = 4249 +const shipMissingSlotsError = 4250 +const shipMissingMountsError = 4251 +const shipMissingCrewError = 4252 +const shipExtractDestabilizedError = 4253 +const shipJumpInvalidOriginError = 4254 +const shipJumpInvalidWaypointError = 4255 +const shipJumpOriginUnderConstructionError = 4256 +const shipMissingGasProcessorError = 4257 +const shipMissingGasSiphonsError = 4258 +const shipSiphonInvalidWaypointError = 4259 +const shipSiphonPermissionError = 4260 +const waypointNoYieldError = 4261 +const shipJumpDestinationUnderConstructionError = 4262 +const acceptContractNotAuthorizedError = 4500 +const acceptContractConflictError = 4501 +const fulfillContractDeliveryError = 4502 +const contractDeadlineError = 4503 +const contractFulfilledError = 4504 +const contractNotAcceptedError = 4505 +const contractNotAuthorizedError = 4506 +const shipDeliverTermsError = 4508 +const shipDeliverFulfilledError = 4509 +const shipDeliverInvalidLocationError = 4510 +const existingContractError = 4511 +const marketTradeInsufficientCreditsError = 4600 +const marketTradeNoPurchaseError = 4601 +const marketTradeNotSoldError = 4602 +const marketNotFoundError = 4603 +const marketTradeUnitLimitError = 4604 +const waypointNoFactionError = 4700 +const constructionMaterialNotRequired = 4800 +const constructionMaterialFulfilled = 4801 +const shipConstructionInvalidLocationError = 4802 \ No newline at end of file diff --git a/sdk/spacetraders.json b/sdk/spacetraders.json index fbf86ee..8b1e6a3 100644 --- a/sdk/spacetraders.json +++ b/sdk/spacetraders.json @@ -30,9 +30,15 @@ "id": "responseMapping", "label": "Response Mapping" }, + { + "id": "error", + "label": "API Error handling", + "tooltip": "Handle error response codes from SpaceTrader's API in the process as BPMN error events." + }, { "id": "retries", - "label": "API Retries" + "label": "API Retries", + "tooltip": "Define retries if SpaceTrader's API returns an error response. Useful to handle API rate limiting." }, { "id": "modificationWarning", @@ -6960,6 +6966,60 @@ }, "optional": true }, + { + "id": "customErrorHandling", + "label": "How to handle errors?", + "description": "By default, it maps the an error to a BPMN error event. The error code is the name of the SpaceTrader's error.", + "group": "error", + "binding": { + "type": "zeebe:property", + "name": "custom_error_handling" + }, + "type": "Dropdown", + "choices": [ + { + "name": "BPMN error by name (default)", + "value": "by_error_name" + }, + { + "name": "Custom", + "value": "custom" + } + ], + "value": "by_error_name" + }, + { + "id": "errorExpression", + "label": "Error expression", + "value": "={\n status: error.code,\n error_code: extract(error.message, \"\\d{4}\")[1],\n error_codes: {\n \"4000\":\"cooldownConflictError\",\n \"4001\":\"waypointNoAccessError\",\n \"4100\":\"tokenEmptyError\",\n \"4101\":\"tokenMissingSubjectError\",\n \"4102\":\"tokenInvalidSubjectError\",\n \"4103\":\"missingTokenRequestError\",\n \"4104\":\"invalidTokenRequestError\",\n \"4105\":\"invalidTokenSubjectError\",\n \"4106\":\"accountNotExistsError\",\n \"4107\":\"agentNotExistsError\",\n \"4108\":\"accountHasNoAgentError\",\n \"4109\":\"registerAgentExistsError\",\n \"4110\":\"registerAgentSymbolReservedError\",\n \"4111\":\"registerAgentConflictSymbolError\",\n \"4200\":\"navigateInTransitError\",\n \"4201\":\"navigateInvalidDestinationError\",\n \"4202\":\"navigateOutsideSystemError\",\n \"4203\":\"navigateInsufficientFuelError\",\n \"4204\":\"navigateSameDestinationError\",\n \"4205\":\"shipExtractInvalidWaypointError\",\n \"4206\":\"shipExtractPermissionError\",\n \"4207\":\"shipJumpNoSystemError\",\n \"4208\":\"shipJumpSameSystemError\",\n \"4210\":\"shipJumpMissingModuleError\",\n \"4211\":\"shipJumpNoValidWaypointError\",\n \"4212\":\"shipJumpMissingAntimatterError\",\n \"4214\":\"shipInTransitError\",\n \"4215\":\"shipMissingSensorArraysError\",\n \"4216\":\"purchaseShipCreditsError\",\n \"4217\":\"shipCargoExceedsLimitError\",\n \"4218\":\"shipCargoMissingError\",\n \"4219\":\"shipCargoUnitCountError\",\n \"4220\":\"shipSurveyVerificationError\",\n \"4221\":\"shipSurveyExpirationError\",\n \"4222\":\"shipSurveyWaypointTypeError\",\n \"4223\":\"shipSurveyOrbitError\",\n \"4224\":\"shipSurveyExhaustedError\",\n \"4225\":\"shipRefuelDockedError\",\n \"4226\":\"shipRefuelInvalidWaypointError\",\n \"4227\":\"shipMissingMountsError\",\n \"4228\":\"shipCargoFullError\",\n \"4229\":\"shipJumpFromGateToGateError\",\n \"4230\":\"waypointChartedError\",\n \"4231\":\"shipTransferShipNotFound\",\n \"4232\":\"shipTransferAgentConflict\",\n \"4233\":\"shipTransferSameShipConflict\",\n \"4234\":\"shipTransferLocationConflict\",\n \"4235\":\"warpInsideSystemError\",\n \"4236\":\"shipNotInOrbitError\",\n \"4237\":\"shipInvalidRefineryGoodError\",\n \"4238\":\"shipInvalidRefineryTypeError\",\n \"4239\":\"shipMissingRefineryError\",\n \"4240\":\"shipMissingSurveyorError\",\n \"4241\":\"shipMissingWarpDriveError\",\n \"4242\":\"shipMissingMineralProcessorError\",\n \"4243\":\"shipMissingMiningLasersError\",\n \"4244\":\"shipNotDockedError\",\n \"4245\":\"purchaseShipNotPresentError\",\n \"4246\":\"shipMountNoShipyardError\",\n \"4247\":\"shipMissingMountError\",\n \"4248\":\"shipMountInsufficientCreditsError\",\n \"4249\":\"shipMissingPowerError\",\n \"4250\":\"shipMissingSlotsError\",\n \"4251\":\"shipMissingMountsError\",\n \"4252\":\"shipMissingCrewError\",\n \"4253\":\"shipExtractDestabilizedError\",\n \"4254\":\"shipJumpInvalidOriginError\",\n \"4255\":\"shipJumpInvalidWaypointError\",\n \"4256\":\"shipJumpOriginUnderConstructionError\",\n \"4257\":\"shipMissingGasProcessorError\",\n \"4258\":\"shipMissingGasSiphonsError\",\n \"4259\":\"shipSiphonInvalidWaypointError\",\n \"4260\":\"shipSiphonPermissionError\",\n \"4261\":\"waypointNoYieldError\",\n \"4262\":\"shipJumpDestinationUnderConstructionError\",\n \"4500\":\"acceptContractNotAuthorizedError\",\n \"4501\":\"acceptContractConflictError\",\n \"4502\":\"fulfillContractDeliveryError\",\n \"4503\":\"contractDeadlineError\",\n \"4504\":\"contractFulfilledError\",\n \"4505\":\"contractNotAcceptedError\",\n \"4506\":\"contractNotAuthorizedError\",\n \"4508\":\"shipDeliverTermsError\",\n \"4509\":\"shipDeliverFulfilledError\",\n \"4510\":\"shipDeliverInvalidLocationError\",\n \"4511\":\"existingContractError\",\n \"4600\":\"marketTradeInsufficientCreditsError\",\n \"4601\":\"marketTradeNoPurchaseError\",\n \"4602\":\"marketTradeNotSoldError\",\n \"4603\":\"marketNotFoundError\",\n \"4604\":\"marketTradeUnitLimitError\",\n \"4700\":\"waypointNoFactionError\",\n \"4800\":\"constructionMaterialNotRequired\",\n \"4801\":\"constructionMaterialFulfilled\",\n \"4802\":\"shipConstructionInvalidLocationError\"\n },\n bpmn_error_code: get or else(get value(error_codes, error_code), error_code),\n bpmn_error_message: substring(extract(error.message, \"\\\"message\\\":\\\"(\\w|\\d|\\s|\\.|\\-)+\")[1], 12),\n result: \n if status = \"400\" \n then bpmnError(bpmn_error_code, bpmn_error_message)\n else null\n}.result", + "group": "error", + "binding": { + "key": "errorExpression", + "type": "zeebe:taskHeader" + }, + "type": "Hidden", + "condition": { + "property": "customErrorHandling", + "equals": "by_error_name" + } + }, + { + "id": "customErrorExpression", + "label": "Error expression", + "description": "Expression to handle errors. Details in the documentation.", + "value": "=if error.code = \"400\"\nthen bpmnError(\"error-1\", \"Something wrong.\")\nelse null", + "feel": "required", + "group": "error", + "binding": { + "key": "errorExpression", + "type": "zeebe:taskHeader" + }, + "type": "Text", + "condition": { + "property": "customErrorHandling", + "equals": "custom" + } + }, { "id": "retryCount", "label": "Retries", From 496d6b09b221685e0a2683cc29e377b249fa0aae Mon Sep 17 00:00:00 2001 From: Philipp Ossler Date: Fri, 15 Dec 2023 15:02:04 +0100 Subject: [PATCH 4/4] docs: Update SDK usage --- assets/space-traders-sdk-authentication.png | Bin 0 -> 7115 bytes assets/space-traders-sdk-error-handling.png | Bin 0 -> 14568 bytes assets/space-traders-sdk-retries.png | Bin 0 -> 12196 bytes sdk/README.md | 27 ++++++++++++++++++++ 4 files changed, 27 insertions(+) create mode 100644 assets/space-traders-sdk-authentication.png create mode 100644 assets/space-traders-sdk-error-handling.png create mode 100644 assets/space-traders-sdk-retries.png diff --git a/assets/space-traders-sdk-authentication.png b/assets/space-traders-sdk-authentication.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2c7da003df580d5f555cc1986ea97dbb20abec GIT binary patch literal 7115 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 q`hRrT_;inw@g|Uwr)?Z1f*7FDPhyMZvl>c%7 literal 0 HcmV?d00001 diff --git a/assets/space-traders-sdk-error-handling.png b/assets/space-traders-sdk-error-handling.png new file mode 100644 index 0000000000000000000000000000000000000000..2410a929afee963e22955805b2c88f6947df32d7 GIT binary patch literal 14568 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 literal 0 HcmV?d00001 diff --git a/assets/space-traders-sdk-retries.png b/assets/space-traders-sdk-retries.png new file mode 100644 index 0000000000000000000000000000000000000000..828e774af216536d580118526c1a9408595271e6 GIT binary patch literal 12196 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%0Dli2qN>iGNZ1OmOXR>lNC#6gT#Y( z9v7%Ijctp>O2xrsab#oPIbQ5`z-|aw0@*t&6=)VRrXFod5YwccBms?$+!UYtPgUr4 zugZsh(71>s8iJDFl*6VHbVEi%JMZ4e1LBYusF$?LXe=nk`IXYG#4lSBZizgRl0S#RZQOB5M=)5-KO%#5SBs0TeHp?s6a4Z|A|xoDSfaZG`V> zo;)v_X_*fgq2LD%w*)d!^sX)b@m*nYECy{=Rhz6!h^RYVKPb%Tfd7 zp)mdaRP@gII}S0nMe!@ey_}zmV~BDE3Sj4Vw&zFu_gfHsc|(;s{Iav%9_KcdpeP=w z#M4$%u1q+(;@Mb%EU9c{(<|j^UJeqF9BD~@b$!avVh^01f_5p%Vq-oSo5r~o;Ex#v z?6vJ)I?$pH*43#waPyIeGi=s$(qKNw0v=s&t9q;OhDtJf4Sti|ZAv&pgkM*@g+#pH zA9gI9xN=_AW%^t!HsB%l91+e``$|r(Z!k)1<{GVL5;-iD(z@xvL^7jWPg**_MK>no$Ld($eL6cxy> zMfUZm%cBuBck=?qSvh*trJ{&d4d*DQhsNTn6yQCIlq8>C#9+LDl+%YyiWZbG`j6hA z0-XA)Inl)CBl`GsI{;P{@NhQLzx#t5#v8iQ3N|qr8`7`{{EYjtg%u4L%IMXjmV^36 zOGiqI`u9Zs?5O<3n#w}ilVDi`&ugC>D$B6mpEHq(x>d7W>L3eTZi~BxDBA{iHbl&B z`cjAXyw;cgsP^_SrGtr`9Nl2K&m@WLPex~ogi?h%{UF)epUu1!tk&eqA;Y{Su2rwQ zg}SyIXd@^*>Q_YqgQ`v`0-9XRz6%Gvl0zx)On=s`m{nEc3qn>PG&T*c{qQ&jv&&@Q zfOGh@-2#QuhBp=G)OAe!N>Rybxg1?QcJ_KU{N;Aa0(k`#>b7`L zv#G^f7`?hnkus#;WrIqv3hR88(O|C%pa*DnGQdn7R z&L3g(R@Y)VyFQ+b?Yfo0;Sb3=1x`qYzhytLZKFD%Ac6l_vK#M61to+xJ9G(@zG^1S zS?x%6uf-Xi1bE(yZcAFqG6|#u97r>TJl)n;r~^^pbxA<)FMDuGUA>kKuaUiwIC<%8 z0ULS4&=fdo7fhF|Qw3I>43?iCR)F;0WjAqWNH%hbz<%x-TO3;6#P& zywTMs=9V{(-a`2%TB9=d{+~F0y>g-^kB6*F=QVXf?bih7f2@wd3$_) zV2brGlvcowY_;5;%eL3)<QAb;8qSvs)mPn|rK_M2Y%Cwq z8VhLJy54w~0+muB%f`f_(O;0BY{K_9U1`lR3XC<|zIm&SN$n|370v2=X@A*G^fB!o z4&c=?Qe{qO$VQmvH2=evtT~_9vRU|kb+fUzZGUBbjn;|%g(7UjrDyu z_rozitZ)t$vN4@uj*+taj!_4c`K8{WutYYvHd}PSDz>KQoAs0YYrH-3sC?c;@s?K+ zbv==>=yljE7|+tuN$CxFhmj@6F3@dxjLJ<*6Q&szz2B7zM?RP<$owcxe+C)^caPUX zC2tR zTGLzG+FF30_R)L)jA%c34u@QWBh~h>5i@R5C=?UfpsTI}WqU3}C%Zj}lbN}%RXCVk z@~Y_PijzXRB9Xm;NT&Rrx2DpC7%AS*uu!aS5#J9?VLY2JQe506z2F3-O+%tVhoDH8 zN9VR1mx!A+4u65}#{daGal;E5HW#XTy%po93hLkgPy3Lm^Vi?MG^Z~Hmc706V) z3KV{O52e%L5vR&WX%W>+%uKl9!>Sq;YCwHYAtkHHA zd2GUd({wb!BStAI7N)^tYP3