@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 +12 -0
- package/package.json +1 -1
- package/src/rfcErrors/RFCErrorToastTemplate.vue +52 -24
- package/src/rfcErrors/index.ts +9 -3
- package/src/rfcErrors/types.ts +14 -3
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
99
|
-
<div
|
|
100
|
-
|
|
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
|
|
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
|
-
|
|
106
|
-
>
|
|
107
|
-
<template v-else
|
|
108
|
-
|
|
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>
|
package/src/rfcErrors/index.ts
CHANGED
|
@@ -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, {
|
|
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
|
-
:
|
|
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
|
|
package/src/rfcErrors/types.ts
CHANGED
|
@@ -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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 {
|