C# 如何通过 Http Request 从 Logic App 触发器获取准确的错误消息而不是默认错误消息?
C# How to get exact error message from Logic App triggered by HttpRequest instead of default error message?
我有一个简单的控制台应用程序,它通过 HttpRequest 调用逻辑应用程序。
当 Logic App 在任何一步失败时,我想获得准确的错误消息,说明它失败的原因。
在 Logic App 中我可以看到错误。
示例:在图像中,它在第 2 步失败,无法将字符串转换为 int。它在说:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
这是我所期望的。
这是我的逻辑应用程序设计:
但是当我在控制台应用程序中调试时,它给我一条消息“服务器没有收到来自上游服务器的响应。请求跟踪 ID 'some random Ids'。”这不是很有用。
这是我的控制台应用程序:
var obj = new
{
Age = "Twenty",
Name = "James"
};
using (var client = new HttpClient())
{
var content = new StringContent(JsonConvert.SerializeObject(obj));
content.Headers.ContentType.MediaType = "application/json";
var response = await client.PostAsync(url, content);
var errorMessage = await response.Content.ReadAsStringAsync();
//errorMessage: {"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
}
那么有没有办法让 C# 响应 return 成为逻辑应用程序第 2 步中的错误消息?
我期望的是:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
不是:
{"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
先谢谢你。
您可以在您的案例中使用 actions('<Your_Previous_Step>')['error']
actions('Parse_JSON')['error']
,这样您就可以检索该特定操作的错误消息。
这是我的逻辑应用程序
我正在通过邮递员对此进行测试。以下是我在邮递员中收到的回复。
确保设置 Configure run after
选项以使流程在失败后仍能正常工作。
更新的答案(一般解决方案)
在这种情况下,您可以初始化一个字符串变量,然后为每个步骤添加 Append to string variable
,以便它可以捕获前面步骤的错误。下面是我的逻辑应用程序的屏幕截图。
我的邮递员回复
注意: 确保为每个操作设置 Configure run after
属性。
您可以使用 Scope
操作来包含绝大多数其他操作,然后如果某些操作失败,您可以捕获它失败的步骤。
您可以将此 JSON 定义加载到您自己的租户中并查看工作版本。
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_array": {
"inputs": {
"from": "@variables('Result')",
"where": "@equals(item()['status'], 'Failed')"
},
"runAfter": {
"Initialize_Result": [
"Succeeded"
]
},
"type": "Query"
},
"Initialize_Error_Message": {
"inputs": {
"variables": [
{
"name": "Error Message",
"type": "string",
"value": "@{body('Filter_array')[0]['error']['message']}"
}
]
},
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Integer_Variable": {
"inputs": {
"variables": [
{
"name": "Integer Variable",
"type": "integer",
"value": 1
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_Result": {
"inputs": {
"variables": [
{
"name": "Result",
"type": "array",
"value": "@result('Scope')"
}
]
},
"runAfter": {
"Scope": [
"Succeeded",
"FAILED"
]
},
"type": "InitializeVariable"
},
"Scope": {
"actions": {
"Set_Integer_Variable_(Step_1)": {
"inputs": {
"name": "Integer Variable",
"value": 2
},
"runAfter": {},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_2)": {
"inputs": {
"name": "Integer Variable",
"value": "@string('Test')"
},
"runAfter": {
"Set_Integer_Variable_(Step_1)": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_3)": {
"inputs": {
"name": "Integer Variable",
"value": 3
},
"runAfter": {
"Set_Integer_Variable_(Step_2)": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"runAfter": {
"Initialize_Integer_Variable": [
"Succeeded"
]
},
"type": "Scope"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 12
},
"recurrence": {
"frequency": "Month",
"interval": 12
},
"type": "Recurrence"
}
}
},
"parameters": {}
}
当然,它会更密集一些,并遵循与正常流程相同的原则,以便在失败后继续下一步,但这将帮助您处理更大的流程。
这就是测试流程的样子...
为了快速解释,中间步骤很简单Set Variable
可以更改导致失败的操作。
在我给你的定义中,第 2 步将失败,但你可以将其更改为第 1 步或第 3 步,你仍然应该看到错误在最后出现,无论范围操作中的哪一步失败.
我建议使用它并查看作用域操作的输出,它在 Initialize Result
步骤中写入变量 Result
。
作为参考,这是来自 Scope
操作的那种信息,您可以使用它们来确定失败的原因。
{
"variables": [
{
"name": "Result",
"type": "Array",
"value": [
{
"name": "Set_Integer_Variable_(Step_1)",
"inputs": {
"name": "Integer Variable",
"value": 2
},
"outputs": {
"body": {
"name": "Integer Variable",
"value": 2
}
},
"startTime": "2022-04-22T06:55:57.8965917Z",
"endTime": "2022-04-22T06:55:57.9281959Z",
"trackingId": "0c93fa70-a552-4776-bce1-8ac889933de9",
"clientTrackingId": "08585509963278112157168286283CU11",
"status": "Succeeded"
},
{
"name": "Set_Integer_Variable_(Step_2)",
"startTime": "2022-04-22T06:55:57.9434709Z",
"endTime": "2022-04-22T06:55:57.9434709Z",
"trackingId": "f82b494b-0ecd-412b-887a-d4b08f4a5751",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "BadRequest",
"status": "Failed",
"error": {
"code": "BadRequest",
"message": "The variable 'Integer Variable' of type 'Integer' cannot be initialized or updated with value of type 'String'. The variable 'Integer Variable' only supports values of types 'Integer'."
}
},
{
"name": "Set_Integer_Variable_(Step_3)",
"startTime": "2022-04-22T06:55:57.9590957Z",
"endTime": "2022-04-22T06:55:57.9590957Z",
"trackingId": "f761d71f-8ec0-4a29-9a8a-a39a81faf660",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "ActionSkipped",
"status": "Skipped",
"error": {
"code": "ActionConditionFailed",
"message": "The execution of template action 'Set_Integer_Variable_(Step_3)' is skipped: the 'runAfter' condition for action 'Set_Integer_Variable_(Step_2)' is not satisfied. Expected status values 'Succeeded' and actual value 'Failed'."
}
}
]
}
]
}
请注意,您仍然需要在 属性后应用 配置 运行 以确保它在 Scope
操作完成后继续...
您需要进行更多错误检查,但我的建议是将所有这些功能包装到另一个 LogicApp 中,您可以在整个租户中重复使用。反正就是这么想的。
我有一个简单的控制台应用程序,它通过 HttpRequest 调用逻辑应用程序。
当 Logic App 在任何一步失败时,我想获得准确的错误消息,说明它失败的原因。
在 Logic App 中我可以看到错误。
示例:在图像中,它在第 2 步失败,无法将字符串转换为 int。它在说:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
这是我所期望的。
这是我的逻辑应用程序设计:
但是当我在控制台应用程序中调试时,它给我一条消息“服务器没有收到来自上游服务器的响应。请求跟踪 ID 'some random Ids'。”这不是很有用。
这是我的控制台应用程序:
var obj = new
{
Age = "Twenty",
Name = "James"
};
using (var client = new HttpClient())
{
var content = new StringContent(JsonConvert.SerializeObject(obj));
content.Headers.ContentType.MediaType = "application/json";
var response = await client.PostAsync(url, content);
var errorMessage = await response.Content.ReadAsStringAsync();
//errorMessage: {"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
}
那么有没有办法让 C# 响应 return 成为逻辑应用程序第 2 步中的错误消息?
我期望的是:
InvalidTemplate. Unable to process template language expressions in action 'Parse_JSON' inputs at line '0' and column '0': 'Required property 'content' expects a value but got null. Path ''.'.
不是:
{"error":{"code":"NoResponse","message":"The server did not receive a response from an upstream server. Request tracking id 'some random Ids'."}}
先谢谢你。
您可以在您的案例中使用 actions('<Your_Previous_Step>')['error']
actions('Parse_JSON')['error']
,这样您就可以检索该特定操作的错误消息。
这是我的逻辑应用程序
我正在通过邮递员对此进行测试。以下是我在邮递员中收到的回复。
确保设置 Configure run after
选项以使流程在失败后仍能正常工作。
更新的答案(一般解决方案)
在这种情况下,您可以初始化一个字符串变量,然后为每个步骤添加 Append to string variable
,以便它可以捕获前面步骤的错误。下面是我的逻辑应用程序的屏幕截图。
我的邮递员回复
注意: 确保为每个操作设置 Configure run after
属性。
您可以使用 Scope
操作来包含绝大多数其他操作,然后如果某些操作失败,您可以捕获它失败的步骤。
您可以将此 JSON 定义加载到您自己的租户中并查看工作版本。
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_array": {
"inputs": {
"from": "@variables('Result')",
"where": "@equals(item()['status'], 'Failed')"
},
"runAfter": {
"Initialize_Result": [
"Succeeded"
]
},
"type": "Query"
},
"Initialize_Error_Message": {
"inputs": {
"variables": [
{
"name": "Error Message",
"type": "string",
"value": "@{body('Filter_array')[0]['error']['message']}"
}
]
},
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Integer_Variable": {
"inputs": {
"variables": [
{
"name": "Integer Variable",
"type": "integer",
"value": 1
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_Result": {
"inputs": {
"variables": [
{
"name": "Result",
"type": "array",
"value": "@result('Scope')"
}
]
},
"runAfter": {
"Scope": [
"Succeeded",
"FAILED"
]
},
"type": "InitializeVariable"
},
"Scope": {
"actions": {
"Set_Integer_Variable_(Step_1)": {
"inputs": {
"name": "Integer Variable",
"value": 2
},
"runAfter": {},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_2)": {
"inputs": {
"name": "Integer Variable",
"value": "@string('Test')"
},
"runAfter": {
"Set_Integer_Variable_(Step_1)": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Set_Integer_Variable_(Step_3)": {
"inputs": {
"name": "Integer Variable",
"value": 3
},
"runAfter": {
"Set_Integer_Variable_(Step_2)": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"runAfter": {
"Initialize_Integer_Variable": [
"Succeeded"
]
},
"type": "Scope"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"Recurrence": {
"evaluatedRecurrence": {
"frequency": "Month",
"interval": 12
},
"recurrence": {
"frequency": "Month",
"interval": 12
},
"type": "Recurrence"
}
}
},
"parameters": {}
}
当然,它会更密集一些,并遵循与正常流程相同的原则,以便在失败后继续下一步,但这将帮助您处理更大的流程。
这就是测试流程的样子...
为了快速解释,中间步骤很简单Set Variable
可以更改导致失败的操作。
在我给你的定义中,第 2 步将失败,但你可以将其更改为第 1 步或第 3 步,你仍然应该看到错误在最后出现,无论范围操作中的哪一步失败.
我建议使用它并查看作用域操作的输出,它在 Initialize Result
步骤中写入变量 Result
。
作为参考,这是来自 Scope
操作的那种信息,您可以使用它们来确定失败的原因。
{
"variables": [
{
"name": "Result",
"type": "Array",
"value": [
{
"name": "Set_Integer_Variable_(Step_1)",
"inputs": {
"name": "Integer Variable",
"value": 2
},
"outputs": {
"body": {
"name": "Integer Variable",
"value": 2
}
},
"startTime": "2022-04-22T06:55:57.8965917Z",
"endTime": "2022-04-22T06:55:57.9281959Z",
"trackingId": "0c93fa70-a552-4776-bce1-8ac889933de9",
"clientTrackingId": "08585509963278112157168286283CU11",
"status": "Succeeded"
},
{
"name": "Set_Integer_Variable_(Step_2)",
"startTime": "2022-04-22T06:55:57.9434709Z",
"endTime": "2022-04-22T06:55:57.9434709Z",
"trackingId": "f82b494b-0ecd-412b-887a-d4b08f4a5751",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "BadRequest",
"status": "Failed",
"error": {
"code": "BadRequest",
"message": "The variable 'Integer Variable' of type 'Integer' cannot be initialized or updated with value of type 'String'. The variable 'Integer Variable' only supports values of types 'Integer'."
}
},
{
"name": "Set_Integer_Variable_(Step_3)",
"startTime": "2022-04-22T06:55:57.9590957Z",
"endTime": "2022-04-22T06:55:57.9590957Z",
"trackingId": "f761d71f-8ec0-4a29-9a8a-a39a81faf660",
"clientTrackingId": "08585509963278112157168286283CU11",
"code": "ActionSkipped",
"status": "Skipped",
"error": {
"code": "ActionConditionFailed",
"message": "The execution of template action 'Set_Integer_Variable_(Step_3)' is skipped: the 'runAfter' condition for action 'Set_Integer_Variable_(Step_2)' is not satisfied. Expected status values 'Succeeded' and actual value 'Failed'."
}
}
]
}
]
}
请注意,您仍然需要在 属性后应用 配置 运行 以确保它在 Scope
操作完成后继续...
您需要进行更多错误检查,但我的建议是将所有这些功能包装到另一个 LogicApp 中,您可以在整个租户中重复使用。反正就是这么想的。