@andersundsehr/storybook-typo3 0.1.11 ā 0.1.12
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.
@@ -6,7 +6,7 @@ export async function fetchComponent(component) {
|
|
6
6
|
alert(message);
|
7
7
|
throw new Error(message);
|
8
8
|
}
|
9
|
-
const data = await fetchWithUserRetry(url + '/_storybook/componentMeta?viewHelper=' + component, {}, 'metadata for component `' + component + '`
|
9
|
+
const data = await fetchWithUserRetry(url + '/_storybook/componentMeta?viewHelper=' + component, {}, 'metadata for component `' + component + '`');
|
10
10
|
return {
|
11
11
|
fullName: component,
|
12
12
|
name: component.split(':')[1],
|
@@ -32,7 +32,7 @@ export async function fetchPreviewConfig(currentGlobals) {
|
|
32
32
|
'Content-Type': 'application/json',
|
33
33
|
},
|
34
34
|
body: JSON.stringify({ globals }),
|
35
|
-
}, 'preview config
|
35
|
+
}, 'preview config');
|
36
36
|
}
|
37
37
|
export function initGlobalsHandling(initalGlobalTypes) {
|
38
38
|
const channel = addons.getChannel();
|
@@ -15,6 +15,6 @@ export async function fetchRenderAction(urlA, id, params, storyContext) {
|
|
15
15
|
return await fetchWithUserRetry(url + '/_storybook/render', {
|
16
16
|
method: 'POST',
|
17
17
|
body: JSON.stringify(body),
|
18
|
-
}, 'rendering component
|
18
|
+
}, 'rendering component', 'text');
|
19
19
|
}
|
20
20
|
;
|
@@ -1 +1,3 @@
|
|
1
|
-
|
1
|
+
type PossibleResults = string | object;
|
2
|
+
export declare function fetchWithUserRetry<T extends PossibleResults>(url: string, options: RequestInit, message: string, resultType?: 'json' | 'text'): Promise<T>;
|
3
|
+
export {};
|
@@ -1,11 +1,11 @@
|
|
1
1
|
/*
|
2
2
|
We want to make it obvious for the user what he has to do.
|
3
3
|
|
4
|
-
We have 2 different
|
4
|
+
We have 2 different use cases:
|
5
5
|
- background fetches (componentMeta & preview)
|
6
6
|
- html Fetches
|
7
7
|
|
8
|
-
most of the time the user has to do something in
|
8
|
+
most of the time the user has to do something in their IDE to fix the problem.
|
9
9
|
So we want to show a message that tells the user what he has to do.
|
10
10
|
|
11
11
|
In the case of a background fetch, we want to show the full error in the console.
|
@@ -13,40 +13,112 @@ And give the user a alert with the error message and a retry button.
|
|
13
13
|
|
14
14
|
In the case of a html fetch, we want to show the error as html response?
|
15
15
|
- yes: because the user can see the error in the browser and can fix it
|
16
|
-
- no: because storybook
|
16
|
+
- no: because storybook does not understand that it is an error
|
17
17
|
|
18
18
|
In any case we should get the error in json so we can handle it in the frontend as we like.
|
19
|
-
|
19
|
+
Sometimes it can still be text/html so we need to handle that as well.
|
20
20
|
*/
|
21
|
-
export async function fetchWithUserRetry(url, options, message,
|
22
|
-
options = { ...options }; // Clone options to avoid mutating the original
|
23
|
-
options.signal = options.signal || AbortSignal.timeout(5000);
|
21
|
+
export async function fetchWithUserRetry(url, options, message, resultType = 'json') {
|
24
22
|
try {
|
23
|
+
options = { ...options }; // Clone options to avoid mutating the original
|
24
|
+
options.signal = options.signal || AbortSignal.timeout(5000);
|
25
25
|
const response = await fetch(url, options);
|
26
26
|
if (!response.ok) {
|
27
|
-
|
28
|
-
// if (responseBody) {
|
29
|
-
// responseBody += '\n';
|
30
|
-
// }
|
31
|
-
// throw new Error(`${responseBody}HTTP ${response.status}\nURL: ${url}\nError while fetching ${message}`);
|
27
|
+
return retry(response, url, options, message, resultType);
|
32
28
|
}
|
33
|
-
|
34
|
-
return await response.text();
|
35
|
-
}
|
36
|
-
return await response.json();
|
29
|
+
return (await response[resultType]());
|
37
30
|
}
|
38
31
|
catch (error) {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
32
|
+
return retry(error, url, options, message, resultType);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
async function retry(errorOrResponse, url, options, message, resultType) {
|
36
|
+
const errorType = await getErrorExplanation(errorOrResponse);
|
37
|
+
let exception = errorOrResponse instanceof Error ? errorOrResponse : undefined;
|
38
|
+
let confirmationMessage = '';
|
39
|
+
if (errorType.errorType === 'network') {
|
40
|
+
confirmationMessage = `š+š« A network error occurred while fetching ${message} from TYPO3:\n\n`
|
41
|
+
+ `š¬ ${errorType.message}\n\n`
|
42
|
+
+ `ā© Please check your network connection and try again.\n\n`
|
43
|
+
+ `š url: ${url}\n\n`;
|
44
|
+
exception = new Error(`Network error: ${errorType.message}`);
|
45
|
+
}
|
46
|
+
else if (errorType.errorType === 'extension') {
|
47
|
+
if (resultType === 'text') {
|
48
|
+
// no retry via confirm()
|
49
|
+
return errorType.errorHtml;
|
49
50
|
}
|
50
|
-
|
51
|
+
confirmationMessage = `š„ An error occurred while fetching ${message} from TYPO3:\n\n`
|
52
|
+
+ `š¬ ${errorType.reason}\n\n`
|
53
|
+
+ `${errorType.stackTrace ? `šµš»āāļø Stack trace: ${errorType.stackTrace}\n\n` : ''}`
|
54
|
+
+ `š url: ${url}\n\n`;
|
55
|
+
exception = new Error(`Extension error: ${errorType.reason}`);
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
if (resultType === 'text' && errorType.message) {
|
59
|
+
// no retry via confirm()
|
60
|
+
return errorType.message;
|
61
|
+
}
|
62
|
+
// unknown error
|
63
|
+
confirmationMessage = `š³ An error occurred while fetching ${message} from TYPO3:\n\n`
|
64
|
+
+ `š¬ ${errorType.message}\n\n`
|
65
|
+
+ `#ļøā£ Status code: ${errorType.statusCode || 'unknown'}\n\n`
|
66
|
+
+ `š url: ${url}\n\n`;
|
67
|
+
}
|
68
|
+
confirmationMessage = confirmationMessage.trim();
|
69
|
+
confirmationMessage = confirmationMessage.length > 700 ? confirmationMessage.substring(0, 700 - 3) + '\nā¦' : confirmationMessage;
|
70
|
+
const retry = confirm(confirmationMessage + '\n\n Do you want to retry šā');
|
71
|
+
if (retry) {
|
72
|
+
options.signal = undefined;
|
73
|
+
return fetchWithUserRetry(url, options, message, resultType);
|
74
|
+
}
|
75
|
+
throw exception || new Error(`Failed to fetch ${message} from TYPO3: ${JSON.stringify(errorType)}`);
|
76
|
+
}
|
77
|
+
async function getErrorExplanation(errorOrResponse) {
|
78
|
+
if (errorOrResponse instanceof Response) {
|
79
|
+
let text = undefined;
|
80
|
+
try {
|
81
|
+
text = await errorOrResponse.text();
|
82
|
+
}
|
83
|
+
catch (e) {
|
84
|
+
return {
|
85
|
+
errorType: 'unknown',
|
86
|
+
message: `Failed to read response from TYPO3: ${errorOrResponse.status}\n ${errorOrResponse.statusText}`,
|
87
|
+
};
|
88
|
+
}
|
89
|
+
try {
|
90
|
+
const extensionError = JSON.parse(text);
|
91
|
+
if (extensionError && typeof extensionError === 'object' && 'errorType' in extensionError && extensionError.errorType === 'extension') {
|
92
|
+
return extensionError;
|
93
|
+
}
|
94
|
+
return {
|
95
|
+
errorType: 'unknown',
|
96
|
+
statusCode: errorOrResponse.status,
|
97
|
+
message: `Received an unexpected response from TYPO3: ${errorOrResponse.status}\n ${JSON.stringify(extensionError)}`,
|
98
|
+
};
|
99
|
+
}
|
100
|
+
catch (e) {
|
101
|
+
console.warn('āļø Failed to parse JSON from TYPO3 response:', e);
|
102
|
+
}
|
103
|
+
return {
|
104
|
+
errorType: 'unknown',
|
105
|
+
message: `Received an unexpected response from TYPO3: ${errorOrResponse.status}\n ${text}`,
|
106
|
+
};
|
107
|
+
}
|
108
|
+
if (errorOrResponse instanceof Error) {
|
109
|
+
return {
|
110
|
+
errorType: 'network',
|
111
|
+
message: errorOrResponse.message,
|
112
|
+
};
|
113
|
+
}
|
114
|
+
if (typeof errorOrResponse === 'string') {
|
115
|
+
return {
|
116
|
+
errorType: 'unknown',
|
117
|
+
message: errorOrResponse,
|
118
|
+
};
|
51
119
|
}
|
120
|
+
return {
|
121
|
+
errorType: 'unknown',
|
122
|
+
message: `An unknown error occurred: ${JSON.stringify(errorOrResponse) || ''}`,
|
123
|
+
};
|
52
124
|
}
|
package/package.json
CHANGED