0
Workspace or Schedule error handler Failure
One script reply has been approved by the moderators Verified

Error handler script sending an error message to a Microsoft Teams channel. It can be used for both a global workspace error handler and specific schedules error handlers

NOTE: this script uses the Microsoft Teams workspace settings resource (EE only)

Created by alex308 34 days ago Viewed 4184 times
0
Submitted by alex308 Bun
Verified 34 days ago
1
import dayjs from 'dayjs'
2
import * as wmill from "windmill-client"
3

4
function formatError(error: any) {
5
  if (error.stack && error.name && error.message) {
6
    return `*${error.name}: ${error.message}*\`\`\`\n${error.stack}\n\`\`\``;
7
  } else {
8
    return `\n${JSON.stringify(error, null, 2)}\n`;
9
  }
10
}
11

12
export async function main(
13
  workspace_id: string,
14
  job_id: string, // The UUID of the job that errored
15
  path: string, // The path of the script or flow that errored
16
  is_flow: boolean, // Whether the runnable is a flow
17
  schedule_path: string, // The path of the schedule
18
  error: object, // The error details
19
  started_at: string, // The start datetime of the latest job that failed
20
  failed_times: number, // Minimum number of times the schedule failed before calling the error handler
21
  channel: string,
22
) {
23
  const baseUrl = process.env["WM_BASE_URL"];
24
  const scheduleUrl = baseUrl + "/runs?schedule_path=" +
25
    encodeURIComponent(schedule_path) + "&workspace=" + encodeURIComponent(workspace_id);
26
  const scriptOrFlowRunUrl = baseUrl + (is_flow ? "/flows/get/" : "/scripts/get/") +
27
    path + "?workspace=" + encodeURIComponent(workspace_id);
28
  const jobRunUrl = baseUrl + "/run/" + job_id + "?workspace=" + encodeURIComponent(workspace_id);
29

30
  let mdText = ""
31
  if (schedule_path === undefined) {
32
    mdText = `*Run [${job_id}](${jobRunUrl}) of ${is_flow ? "flow" : "script"} [${path}](${scriptOrFlowRunUrl}) failed*${failed_times > 1 ? (" " + failed_times + " times in a row") : ""}:`
33
  } else {
34
    mdText = `*Schedule [${schedule_path}](${scheduleUrl}) failed*${failed_times > 1 ? (" " + failed_times + " times in a row") : ""}:\n- Run [${job_id}](${jobRunUrl}) of ${is_flow ? "flow" : "script"}: [${path}](${scriptOrFlowRunUrl})`
35
  }
36

37
  const lastFailureText = `Last failure at: ${dayjs(started_at).format("DD.MM.YYYY HH:mm (Z)")}\n`
38

39
  await wmill.TeamsService.sendMessageToConversation(
40
    {
41
      requestBody: {
42
        conversation_id: channel,
43
        success: true,
44
        text: mdText,
45
        card_block: {
46
          "type": "message",
47
          "attachments": [
48
            {
49
              "contentType": "application/vnd.microsoft.card.adaptive",
50
              "content": {
51
                "type": "AdaptiveCard",
52
                "body": [
53
                  {
54
                    "type": "TextBlock",
55
                    "size": "Medium",
56
                    "weight": "Bolder",
57
                    "text": "Error Handler"
58
                  },
59
                  {
60
                    "type": "ColumnSet",
61
                    "columns": [
62
                      {
63
                        "type": "Column",
64
                        "items": [
65
                          {
66
                            "type": "Icon",
67
                            "name": "Warning",
68
                            "size": "Medium",
69
                            "style": "Filled",
70
                            "color": "Attention"
71
                          }
72
                        ],
73
                        "width": "auto"
74
                      },
75
                      {
76
                        "type": "Column",
77
                        "items": [
78
                          {
79
                            "type": "TextBlock",
80
                            "text": mdText,
81
                            "wrap": true
82
                          },
83
                          {
84
                            "type": "TextBlock",
85
                            "text": lastFailureText,
86
                            "wrap": true
87
                          },
88
                          {
89
                            "type": "CodeBlock",
90
                            "codeSnippet": formatError(error),
91
                            "language": "JavaScript"
92
                          }
93
                        ],
94
                        "width": "stretch"
95
                      }
96
                    ]
97
                  }
98
                ],
99
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
100
                "version": "1.6"
101
              },
102
            }
103
          ]
104
        }
105
      }
106
    }
107
  )
108
}