@futdevpro/fsm-dynamo 1.20.105 → 1.20.107
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/build/_collections/utils/extract-error-message.util.d.ts +15 -4
- package/build/_collections/utils/extract-error-message.util.d.ts.map +1 -1
- package/build/_collections/utils/extract-error-message.util.js +35 -6
- package/build/_collections/utils/extract-error-message.util.js.map +1 -1
- package/build/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.d.ts +10 -0
- package/build/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.d.ts.map +1 -1
- package/build/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.js +10 -0
- package/build/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.js.map +1 -1
- package/build-esm/_collections/utils/extract-error-message.util.js +34 -6
- package/build-esm/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.js +10 -0
- package/package.json +2 -2
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import { DyFM_AnyError } from '../../_models/control-models/error.control-model';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-FSMED-016 — the default user-facing texts `DyFM_extractErrorMessage` falls back to when the error carries no user
|
|
4
|
+
* message (exported so a UI can compare / translate them).
|
|
5
|
+
*/
|
|
6
|
+
export declare const DyFM_ERROR_MESSAGE_FALLBACKS: {
|
|
7
|
+
readonly noConnection: string;
|
|
8
|
+
readonly timeout: string;
|
|
9
|
+
readonly serverError: string;
|
|
10
|
+
readonly generic: string;
|
|
11
|
+
};
|
|
2
12
|
/**
|
|
3
13
|
* Options for `DyFM_extractErrorMessage`.
|
|
4
14
|
*/
|
|
@@ -9,8 +19,9 @@ export interface DyFM_ExtractErrorMessage_Options {
|
|
|
9
19
|
*/
|
|
10
20
|
prefix?: string;
|
|
11
21
|
/**
|
|
12
|
-
* Fallback string when no usable message can be extracted.
|
|
13
|
-
*
|
|
22
|
+
* Fallback string when no usable message can be extracted. When NOT given, the fallback is status-aware and written
|
|
23
|
+
* for the END USER (BFR-FSMED-016): no connection (status 0) · timeout (status 408 / 504, `TimeoutError`) · server
|
|
24
|
+
* error (other 5xx) · anything else. An explicit `fallback` always wins.
|
|
14
25
|
*/
|
|
15
26
|
fallback?: string;
|
|
16
27
|
/**
|
|
@@ -56,7 +67,7 @@ export interface DyFM_ExtractErrorMessage_Options {
|
|
|
56
67
|
* `err.error.message` (debug / transport texts — never a user message by default)
|
|
57
68
|
* 6. ONLY with `includeRawPayload: true`: the JSON-stringified payload (circular-safe; first 200 chars),
|
|
58
69
|
* prefixed with 'Malformed error: ' (default: skipped — raw JSON is not a user message)
|
|
59
|
-
* 7. `options.fallback
|
|
70
|
+
* 7. `options.fallback`, else the status-aware user text (`DyFM_ERROR_MESSAGE_FALLBACKS`)
|
|
60
71
|
*
|
|
61
72
|
* Only when `includeHttpStatus: true` (opt-in, default `false`) and the input
|
|
62
73
|
* looks like a HttpErrorResponse, the status + statusText are appended in
|
|
@@ -70,7 +81,7 @@ export interface DyFM_ExtractErrorMessage_Options {
|
|
|
70
81
|
* this.formError = DyFM_extractErrorMessage(err, { prefix: 'Login' });
|
|
71
82
|
* // → 'Login: Bad credentials' (the raw `err` keeps the status for the log / copy chain)
|
|
72
83
|
* // OR
|
|
73
|
-
* // → 'Login:
|
|
84
|
+
* // → 'Login: Cannot reach the server. Check your connection and try again.' (status 0, no user message)
|
|
74
85
|
* // never 'Login: undefined undefined'
|
|
75
86
|
* }
|
|
76
87
|
* ```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-error-message.util.d.ts","sourceRoot":"","sources":["../../../src/_collections/utils/extract-error-message.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAc,MAAM,kDAAkD,CAAC;AAG7F;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB
|
|
1
|
+
{"version":3,"file":"extract-error-message.util.d.ts","sourceRoot":"","sources":["../../../src/_collections/utils/extract-error-message.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAc,MAAM,kDAAkD,CAAC;AAG7F;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE;IACzC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAM1B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,aAAa,GAAG,OAAO,EAC5B,OAAO,CAAC,EAAE,gCAAgC,GACzC,MAAM,CA6DR;AA6DD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,aAAa,GAAG,OAAO,EAC5B,MAAM,EAAE,MAAM,GACb,MAAM,CAIR;AAiBD,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,GAC3C,IAAI,CAEN;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAmBN"}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_ERROR_MESSAGE_FALLBACKS = void 0;
|
|
3
4
|
exports.DyFM_extractErrorMessage = DyFM_extractErrorMessage;
|
|
4
5
|
exports.DyFM_formatError = DyFM_formatError;
|
|
5
6
|
exports.DyFM_registerMalformedErrorSink = DyFM_registerMalformedErrorSink;
|
|
6
7
|
exports.DyFM_reportMalformedError = DyFM_reportMalformedError;
|
|
8
|
+
/**
|
|
9
|
+
* BFR-FSMED-016 — the default user-facing texts `DyFM_extractErrorMessage` falls back to when the error carries no user
|
|
10
|
+
* message (exported so a UI can compare / translate them).
|
|
11
|
+
*/
|
|
12
|
+
exports.DyFM_ERROR_MESSAGE_FALLBACKS = {
|
|
13
|
+
noConnection: 'Cannot reach the server. Check your connection and try again.',
|
|
14
|
+
timeout: 'The server took too long to answer. Please try again.',
|
|
15
|
+
serverError: 'The server could not complete the request. Please try again in a moment.',
|
|
16
|
+
generic: 'Something went wrong. Please try again.',
|
|
17
|
+
};
|
|
7
18
|
/**
|
|
8
19
|
* Universal error → human-readable string extractor. **Never** returns the
|
|
9
20
|
* literal string `'undefined'` (or `'undefined undefined'`), `'[object Object]'`,
|
|
@@ -22,7 +33,7 @@ exports.DyFM_reportMalformedError = DyFM_reportMalformedError;
|
|
|
22
33
|
* `err.error.message` (debug / transport texts — never a user message by default)
|
|
23
34
|
* 6. ONLY with `includeRawPayload: true`: the JSON-stringified payload (circular-safe; first 200 chars),
|
|
24
35
|
* prefixed with 'Malformed error: ' (default: skipped — raw JSON is not a user message)
|
|
25
|
-
* 7. `options.fallback
|
|
36
|
+
* 7. `options.fallback`, else the status-aware user text (`DyFM_ERROR_MESSAGE_FALLBACKS`)
|
|
26
37
|
*
|
|
27
38
|
* Only when `includeHttpStatus: true` (opt-in, default `false`) and the input
|
|
28
39
|
* looks like a HttpErrorResponse, the status + statusText are appended in
|
|
@@ -36,19 +47,17 @@ exports.DyFM_reportMalformedError = DyFM_reportMalformedError;
|
|
|
36
47
|
* this.formError = DyFM_extractErrorMessage(err, { prefix: 'Login' });
|
|
37
48
|
* // → 'Login: Bad credentials' (the raw `err` keeps the status for the log / copy chain)
|
|
38
49
|
* // OR
|
|
39
|
-
* // → 'Login:
|
|
50
|
+
* // → 'Login: Cannot reach the server. Check your connection and try again.' (status 0, no user message)
|
|
40
51
|
* // never 'Login: undefined undefined'
|
|
41
52
|
* }
|
|
42
53
|
* ```
|
|
43
54
|
*/
|
|
44
55
|
function DyFM_extractErrorMessage(err, options) {
|
|
45
56
|
const includeHttpStatus = options?.includeHttpStatus === true;
|
|
46
|
-
const fallback = options?.fallback
|
|
47
|
-
?? 'Unexpected error (no detail in payload — check server logs).';
|
|
48
57
|
const prefix = options?.prefix ? `${options.prefix}: ` : '';
|
|
49
58
|
// Null/undefined/empty
|
|
50
59
|
if (err === null || err === undefined) {
|
|
51
|
-
return `${prefix}${fallback}`;
|
|
60
|
+
return `${prefix}${options?.fallback ?? exports.DyFM_ERROR_MESSAGE_FALLBACKS.generic}`;
|
|
52
61
|
}
|
|
53
62
|
// String → use as-is
|
|
54
63
|
if (typeof err === 'string') {
|
|
@@ -92,7 +101,27 @@ function DyFM_extractErrorMessage(err, options) {
|
|
|
92
101
|
return `${prefix}Malformed error: ${trimmed}${httpSuffix}`;
|
|
93
102
|
}
|
|
94
103
|
// Total fallback.
|
|
95
|
-
return `${prefix}${fallback}${httpSuffix}`;
|
|
104
|
+
return `${prefix}${options?.fallback ?? _statusAwareFallback(status, e?.name ?? innerError?.name)}${httpSuffix}`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* BFR-FSMED-016 — the USER-facing fallback when the error carries no user message, chosen by what the user can do.
|
|
108
|
+
*
|
|
109
|
+
* The old default ("Unexpected error (no detail in payload — check server logs).") was a developer hint shown to end
|
|
110
|
+
* users on every network outage, gateway error and timeout (measured on the shared FDPNX login form): they cannot
|
|
111
|
+
* check server logs, and "unexpected" tells them nothing. The raw error (status included) stays with the caller.
|
|
112
|
+
*/
|
|
113
|
+
function _statusAwareFallback(status, name) {
|
|
114
|
+
const code = typeof status === 'string' ? Number(status) : (status ?? NaN);
|
|
115
|
+
if (code === 0) {
|
|
116
|
+
return exports.DyFM_ERROR_MESSAGE_FALLBACKS.noConnection;
|
|
117
|
+
}
|
|
118
|
+
if (code === 408 || code === 504 || name === 'TimeoutError') {
|
|
119
|
+
return exports.DyFM_ERROR_MESSAGE_FALLBACKS.timeout;
|
|
120
|
+
}
|
|
121
|
+
if (code >= 500 && code < 600) {
|
|
122
|
+
return exports.DyFM_ERROR_MESSAGE_FALLBACKS.serverError;
|
|
123
|
+
}
|
|
124
|
+
return exports.DyFM_ERROR_MESSAGE_FALLBACKS.generic;
|
|
96
125
|
}
|
|
97
126
|
/**
|
|
98
127
|
* Returns the value if it's a non-empty string, else undefined.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-error-message.util.js","sourceRoot":"","sources":["../../../src/_collections/utils/extract-error-message.util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"extract-error-message.util.js","sourceRoot":"","sources":["../../../src/_collections/utils/extract-error-message.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,16 @@ export declare class DyFM_TextFieldNew_Settings_ControlModel extends DyFM_FieldN
|
|
|
17
17
|
suffix?: string;
|
|
18
18
|
/** Karakter-korlát. */
|
|
19
19
|
maxLength?: number;
|
|
20
|
+
/**
|
|
21
|
+
* BFR-FSMED-016 — the HTML input type (default `'text'`). `'email'` / `'tel'` / `'url'` give the right mobile keyboard
|
|
22
|
+
* and browser validation hints; the value stays a string.
|
|
23
|
+
*/
|
|
24
|
+
inputType?: 'text' | 'email' | 'tel' | 'url' | 'search';
|
|
25
|
+
/**
|
|
26
|
+
* BFR-FSMED-016 — the HTML `autocomplete` token (e.g. `'username'`, `'email'`, `'name'`, `'off'`). Without it the
|
|
27
|
+
* browser / password manager must guess what the field is (measured: the shared login's username field had none).
|
|
28
|
+
*/
|
|
29
|
+
autocomplete?: string;
|
|
20
30
|
/** Initializes the existing defaults and applies caller-provided settings. */
|
|
21
31
|
constructor(set: Partial<DyFM_TextFieldNew_Settings_ControlModel>);
|
|
22
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-field-new-settings.control-model.d.ts","sourceRoot":"","sources":["../../../../../../src/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E;;;;;;GAMG;AACH,qBAAa,uCAAwC,SAAQ,sBAAsB,CAAC,MAAM,CAAC;IAMzF,SAAkB,IAAI,EAAE,eAAe,CAAC,IAAI,CAAwB;IAEpE,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"text-field-new-settings.control-model.d.ts","sourceRoot":"","sources":["../../../../../../src/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E;;;;;;GAMG;AACH,qBAAa,uCAAwC,SAAQ,sBAAsB,CAAC,MAAM,CAAC;IAMzF,SAAkB,IAAI,EAAE,eAAe,CAAC,IAAI,CAAwB;IAEpE,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;IACxD;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8EAA8E;gBAClE,GAAG,EAAE,OAAO,CAAC,uCAAuC,CAAC;CAUlE;AAED,iGAAiG;AACjG,OAAO,EAAE,uCAAuC,IAAI,0BAA0B,EAAE,CAAC"}
|
|
@@ -24,6 +24,16 @@ class DyFM_TextFieldNew_Settings_ControlModel extends field_new_settings_control
|
|
|
24
24
|
suffix;
|
|
25
25
|
/** Karakter-korlát. */
|
|
26
26
|
maxLength;
|
|
27
|
+
/**
|
|
28
|
+
* BFR-FSMED-016 — the HTML input type (default `'text'`). `'email'` / `'tel'` / `'url'` give the right mobile keyboard
|
|
29
|
+
* and browser validation hints; the value stays a string.
|
|
30
|
+
*/
|
|
31
|
+
inputType;
|
|
32
|
+
/**
|
|
33
|
+
* BFR-FSMED-016 — the HTML `autocomplete` token (e.g. `'username'`, `'email'`, `'name'`, `'off'`). Without it the
|
|
34
|
+
* browser / password manager must guess what the field is (measured: the shared login's username field had none).
|
|
35
|
+
*/
|
|
36
|
+
autocomplete;
|
|
27
37
|
/** Initializes the existing defaults and applies caller-provided settings. */
|
|
28
38
|
constructor(set) {
|
|
29
39
|
super(set);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-field-new-settings.control-model.js","sourceRoot":"","sources":["../../../../../../src/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.ts"],"names":[],"mappings":";;;AAAA,qEAAkE;AAClE,yFAA4E;AAE5E;;;;;;GAMG;AACH,MAAa,uCAAwC,SAAQ,yDAA8B;IACzF,mEAAmE;IACnE;QACE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAC/E,CAAC;IAEiB,IAAI,GAAyB,iCAAe,CAAC,IAAI,CAAC;IAEpE,uEAAuE;IACvE,IAAI,CAAU;IACd,uCAAuC;IACvC,MAAM,CAAU;IAChB,wCAAwC;IACxC,MAAM,CAAU;IAChB,uBAAuB;IACvB,SAAS,CAAU;
|
|
1
|
+
{"version":3,"file":"text-field-new-settings.control-model.js","sourceRoot":"","sources":["../../../../../../src/_modules/ngx-models/_models/control-models/forms-new/text-field-new-settings.control-model.ts"],"names":[],"mappings":";;;AAAA,qEAAkE;AAClE,yFAA4E;AAE5E;;;;;;GAMG;AACH,MAAa,uCAAwC,SAAQ,yDAA8B;IACzF,mEAAmE;IACnE;QACE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAC/E,CAAC;IAEiB,IAAI,GAAyB,iCAAe,CAAC,IAAI,CAAC;IAEpE,uEAAuE;IACvE,IAAI,CAAU;IACd,uCAAuC;IACvC,MAAM,CAAU;IAChB,wCAAwC;IACxC,MAAM,CAAU;IAChB,uBAAuB;IACvB,SAAS,CAAU;IACnB;;;OAGG;IACH,SAAS,CAA+C;IACxD;;;OAGG;IACH,YAAY,CAAU;IAEtB,8EAA8E;IAC9E,YAAY,GAAqD;QAC/D,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,mFAAmF;QACnF,wDAAwD;QACxD,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAqD,GAAG,CAAC;QAE9F,KAAK,YAAY,CAAC;QAElB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;CACF;AAtCD,0FAsCC;AAGmD,6EAA0B"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BFR-FSMED-016 — the default user-facing texts `DyFM_extractErrorMessage` falls back to when the error carries no user
|
|
3
|
+
* message (exported so a UI can compare / translate them).
|
|
4
|
+
*/
|
|
5
|
+
export const DyFM_ERROR_MESSAGE_FALLBACKS = {
|
|
6
|
+
noConnection: 'Cannot reach the server. Check your connection and try again.',
|
|
7
|
+
timeout: 'The server took too long to answer. Please try again.',
|
|
8
|
+
serverError: 'The server could not complete the request. Please try again in a moment.',
|
|
9
|
+
generic: 'Something went wrong. Please try again.',
|
|
10
|
+
};
|
|
1
11
|
/**
|
|
2
12
|
* Universal error → human-readable string extractor. **Never** returns the
|
|
3
13
|
* literal string `'undefined'` (or `'undefined undefined'`), `'[object Object]'`,
|
|
@@ -16,7 +26,7 @@
|
|
|
16
26
|
* `err.error.message` (debug / transport texts — never a user message by default)
|
|
17
27
|
* 6. ONLY with `includeRawPayload: true`: the JSON-stringified payload (circular-safe; first 200 chars),
|
|
18
28
|
* prefixed with 'Malformed error: ' (default: skipped — raw JSON is not a user message)
|
|
19
|
-
* 7. `options.fallback
|
|
29
|
+
* 7. `options.fallback`, else the status-aware user text (`DyFM_ERROR_MESSAGE_FALLBACKS`)
|
|
20
30
|
*
|
|
21
31
|
* Only when `includeHttpStatus: true` (opt-in, default `false`) and the input
|
|
22
32
|
* looks like a HttpErrorResponse, the status + statusText are appended in
|
|
@@ -30,19 +40,17 @@
|
|
|
30
40
|
* this.formError = DyFM_extractErrorMessage(err, { prefix: 'Login' });
|
|
31
41
|
* // → 'Login: Bad credentials' (the raw `err` keeps the status for the log / copy chain)
|
|
32
42
|
* // OR
|
|
33
|
-
* // → 'Login:
|
|
43
|
+
* // → 'Login: Cannot reach the server. Check your connection and try again.' (status 0, no user message)
|
|
34
44
|
* // never 'Login: undefined undefined'
|
|
35
45
|
* }
|
|
36
46
|
* ```
|
|
37
47
|
*/
|
|
38
48
|
export function DyFM_extractErrorMessage(err, options) {
|
|
39
49
|
const includeHttpStatus = options?.includeHttpStatus === true;
|
|
40
|
-
const fallback = options?.fallback
|
|
41
|
-
?? 'Unexpected error (no detail in payload — check server logs).';
|
|
42
50
|
const prefix = options?.prefix ? `${options.prefix}: ` : '';
|
|
43
51
|
// Null/undefined/empty
|
|
44
52
|
if (err === null || err === undefined) {
|
|
45
|
-
return `${prefix}${fallback}`;
|
|
53
|
+
return `${prefix}${options?.fallback ?? DyFM_ERROR_MESSAGE_FALLBACKS.generic}`;
|
|
46
54
|
}
|
|
47
55
|
// String → use as-is
|
|
48
56
|
if (typeof err === 'string') {
|
|
@@ -86,7 +94,27 @@ export function DyFM_extractErrorMessage(err, options) {
|
|
|
86
94
|
return `${prefix}Malformed error: ${trimmed}${httpSuffix}`;
|
|
87
95
|
}
|
|
88
96
|
// Total fallback.
|
|
89
|
-
return `${prefix}${fallback}${httpSuffix}`;
|
|
97
|
+
return `${prefix}${options?.fallback ?? _statusAwareFallback(status, e?.name ?? innerError?.name)}${httpSuffix}`;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* BFR-FSMED-016 — the USER-facing fallback when the error carries no user message, chosen by what the user can do.
|
|
101
|
+
*
|
|
102
|
+
* The old default ("Unexpected error (no detail in payload — check server logs).") was a developer hint shown to end
|
|
103
|
+
* users on every network outage, gateway error and timeout (measured on the shared FDPNX login form): they cannot
|
|
104
|
+
* check server logs, and "unexpected" tells them nothing. The raw error (status included) stays with the caller.
|
|
105
|
+
*/
|
|
106
|
+
function _statusAwareFallback(status, name) {
|
|
107
|
+
const code = typeof status === 'string' ? Number(status) : (status ?? NaN);
|
|
108
|
+
if (code === 0) {
|
|
109
|
+
return DyFM_ERROR_MESSAGE_FALLBACKS.noConnection;
|
|
110
|
+
}
|
|
111
|
+
if (code === 408 || code === 504 || name === 'TimeoutError') {
|
|
112
|
+
return DyFM_ERROR_MESSAGE_FALLBACKS.timeout;
|
|
113
|
+
}
|
|
114
|
+
if (code >= 500 && code < 600) {
|
|
115
|
+
return DyFM_ERROR_MESSAGE_FALLBACKS.serverError;
|
|
116
|
+
}
|
|
117
|
+
return DyFM_ERROR_MESSAGE_FALLBACKS.generic;
|
|
90
118
|
}
|
|
91
119
|
/**
|
|
92
120
|
* Returns the value if it's a non-empty string, else undefined.
|
|
@@ -21,6 +21,16 @@ export class DyFM_TextFieldNew_Settings_ControlModel extends DyFM_FieldNew_Setti
|
|
|
21
21
|
suffix;
|
|
22
22
|
/** Karakter-korlát. */
|
|
23
23
|
maxLength;
|
|
24
|
+
/**
|
|
25
|
+
* BFR-FSMED-016 — the HTML input type (default `'text'`). `'email'` / `'tel'` / `'url'` give the right mobile keyboard
|
|
26
|
+
* and browser validation hints; the value stays a string.
|
|
27
|
+
*/
|
|
28
|
+
inputType;
|
|
29
|
+
/**
|
|
30
|
+
* BFR-FSMED-016 — the HTML `autocomplete` token (e.g. `'username'`, `'email'`, `'name'`, `'off'`). Without it the
|
|
31
|
+
* browser / password manager must guess what the field is (measured: the shared login's username field had none).
|
|
32
|
+
*/
|
|
33
|
+
autocomplete;
|
|
24
34
|
/** Initializes the existing defaults and applies caller-provided settings. */
|
|
25
35
|
constructor(set) {
|
|
26
36
|
super(set);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/fsm-dynamo",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.107",
|
|
4
4
|
"description": "Full Stack Model Collection for Dynamic (NodeJS-Typescript) Framework called Dynamo, by Future Development Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "full-stack-package",
|
|
@@ -371,7 +371,7 @@
|
|
|
371
371
|
"uuid": "~11.1.1"
|
|
372
372
|
},
|
|
373
373
|
"devDependencies": {
|
|
374
|
-
"@futdevpro/dynamo-eslint": "1.20.
|
|
374
|
+
"@futdevpro/dynamo-eslint": "1.20.57",
|
|
375
375
|
"@types/jasmine": "~4.3.5",
|
|
376
376
|
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
377
377
|
"@typescript-eslint/parser": "^8.41.0",
|