@knime/hub-features 1.11.5 → 1.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @knime/hub-features
2
2
 
3
+ ## 1.11.7
4
+
5
+ ### Patch Changes
6
+
7
+ - 2e90c18: Add possibility to send and copy stacktrace in RFC errors
8
+
9
+ ## 1.11.6
10
+
11
+ ### Patch Changes
12
+
13
+ - dc12ac4: Adjust payload for RFC error utils
14
+
3
15
  ## 1.11.5
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knime/hub-features",
3
- "version": "1.11.5",
3
+ "version": "1.11.7",
4
4
  "description": "Vue components & composables for shared hub features",
5
5
  "homepage": "https://knime.github.io/webapps-common/",
6
6
  "license": "GPL 3 and Additional Permissions according to Sec. 7 (SEE the file LICENSE)",
@@ -6,17 +6,21 @@ import { Button } from "@knime/components";
6
6
  import CheckIcon from "@knime/styles/img/icons/check.svg";
7
7
  import CopyIcon from "@knime/styles/img/icons/copy.svg";
8
8
 
9
- interface Props {
10
- headline: string; // toast headline, will not be displayed here but needed when copying to clipboard
11
- title: string;
12
- details?: string[];
13
- status: number;
14
- date: Date;
15
- requestId: string;
16
- errorId?: string;
17
- }
9
+ import type { RFCErrorData } from "./types";
18
10
 
19
- const props = defineProps<Props>();
11
+ type Props = {
12
+ headline: string; // toast headline, will not be displayed here but needed when copying to clipboard
13
+ canCopyToClipboard?: boolean;
14
+ } & RFCErrorData;
15
+
16
+ const props = withDefaults(defineProps<Props>(), {
17
+ status: undefined,
18
+ date: undefined,
19
+ details: () => [],
20
+ requestId: undefined,
21
+ errorId: undefined,
22
+ canCopyToClipboard: true,
23
+ });
20
24
  const emits = defineEmits(["showMore"]);
21
25
 
22
26
  const { copy, copied } = useClipboard({
@@ -57,16 +61,34 @@ const errorForClipboard = computed(() => {
57
61
  errorText += `${props.title}\n\n`;
58
62
  errorText += details ? `Details: ${details}\n\n` : "";
59
63
 
60
- errorText += `Status: ${props.status}\n`;
61
- errorText += `Date: ${formattedDate.value}\n`;
62
- errorText += `Request Id: ${props.requestId}\n`;
63
- errorText += props.errorId ? `Error Id: ${props.errorId}\n` : "";
64
+ if (props.status !== undefined) {
65
+ errorText += `Status: ${props.status}\n`;
66
+ }
67
+
68
+ if (props.date) {
69
+ errorText += `Date: ${formattedDate.value}\n`;
70
+ }
71
+
72
+ if (props.requestId) {
73
+ errorText += `Request Id: ${props.requestId}\n`;
74
+ }
75
+
76
+ if (props.errorId) {
77
+ errorText += `Error Id: ${props.errorId}\n`;
78
+ }
79
+
80
+ if (props.stacktrace) {
81
+ errorText += "------\n"; // separator
82
+ errorText += `Stacktrace:\n\n${props.stacktrace}\n`;
83
+ }
64
84
 
65
85
  return errorText;
66
86
  });
67
87
 
68
88
  const copyToClipboard = () => {
69
- copy(errorForClipboard.value);
89
+ copy(errorForClipboard.value).catch((error) => {
90
+ consola.error("Failed to copy to clipboard", { error });
91
+ });
70
92
  };
71
93
 
72
94
  const onShowDetailsClicked = () => {
@@ -95,17 +117,23 @@ const onShowDetailsClicked = () => {
95
117
  </ul>
96
118
  </template>
97
119
  </div>
98
- <div><strong>Status: </strong>{{ status }}</div>
99
- <div><strong>Date: </strong>{{ formattedDate }}</div>
100
- <div><strong>Request id: </strong>{{ requestId }}</div>
120
+
121
+ <div v-if="status !== undefined">
122
+ <strong>Status: </strong>{{ status }}
123
+ </div>
124
+ <div v-if="date"><strong>Date: </strong>{{ formattedDate }}</div>
125
+ <div v-if="requestId"><strong>Request id: </strong>{{ requestId }}</div>
101
126
  <div v-if="errorId"><strong>Error id: </strong>{{ errorId }}</div>
102
- <div class="copy-button-wrapper">
127
+ <div v-if="stacktrace">
128
+ <strong>Stacktrace: </strong>Part of clipboard text
129
+ </div>
130
+ <div v-if="canCopyToClipboard" class="copy-button-wrapper">
103
131
  <Button @click="copyToClipboard">
104
- <template v-if="copied"
105
- ><CheckIcon class="copy-icon" />Error was copied</template
106
- >
107
- <template v-else
108
- ><CopyIcon class="copy-icon" />Copy error to clipboard
132
+ <template v-if="copied">
133
+ <CheckIcon class="copy-icon" />Error was copied
134
+ </template>
135
+ <template v-else>
136
+ <CopyIcon class="copy-icon" />Copy error to clipboard
109
137
  </template>
110
138
  </Button>
111
139
  </div>
@@ -12,13 +12,19 @@ import { RFCError, type RFCErrorData } from "./types";
12
12
  const toToast = ({
13
13
  headline,
14
14
  rfcError,
15
+ canCopyToClipboard = true,
15
16
  }: {
16
17
  headline: string;
17
18
  rfcError: RFCError;
19
+ canCopyToClipboard?: boolean;
18
20
  }): Toast => {
19
21
  const { data } = rfcError;
20
22
 
21
- const rfcErrorToastContent = h(RFCErrorToastTemplate, { headline, ...data });
23
+ const rfcErrorToastContent = h(RFCErrorToastTemplate, {
24
+ headline,
25
+ ...data,
26
+ canCopyToClipboard,
27
+ });
22
28
 
23
29
  return {
24
30
  type: "error",
@@ -39,14 +45,14 @@ const tryParse = (error: FetchError): RFCError | FetchError => {
39
45
 
40
46
  const responseDate = error.response.headers.get("date")
41
47
  ? new Date(error.response.headers.get("date")!)
42
- : new Date();
48
+ : undefined;
43
49
 
44
50
  const rfcErrorData: RFCErrorData = {
45
51
  title: error.data.title as string,
46
52
  details: error.data.details as string[] | undefined,
47
53
  status: error.statusCode as number,
48
54
  date: responseDate,
49
- requestId: error.response.headers.get("x-request-id") ?? "",
55
+ requestId: error.response.headers.get("x-request-id") ?? undefined,
50
56
  errorId: error.response.headers.get("x-error-id") ?? undefined,
51
57
  };
52
58
 
@@ -1,13 +1,24 @@
1
1
  /**
2
2
  * Type based on an RFC-9457 error standard (https://www.rfc-editor.org/rfc/rfc9457)
3
+ * Also see:
4
+ * https://knime-com.atlassian.net/wiki/spaces/SPECS/pages/4126769212/API+Errors+Problem+Details
3
5
  */
4
6
  export type RFCErrorData = {
5
7
  title: string;
8
+ status?: number;
9
+ date?: Date;
6
10
  details?: string[];
7
- status: number;
8
- date: Date;
9
- requestId: string;
11
+ requestId?: string;
12
+ /**
13
+ * Id used to find an error in the Hub logs. Specially relevant
14
+ * when details of the error are not wanted to be exposed to the user.
15
+ */
10
16
  errorId?: string;
17
+ /**
18
+ * Relevant only for the Analytics Platform, since the Hub does not expose
19
+ * stack traces.
20
+ */
21
+ stacktrace?: string;
11
22
  };
12
23
 
13
24
  export class RFCError extends Error {