Skip to content
Snippets Groups Projects
Verified Commit c58d590d authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: optimize rest errors

parent 10b850b7
Branches
Tags
No related merge requests found
...@@ -13,26 +13,26 @@ ...@@ -13,26 +13,26 @@
*/ */
import { import {
assembleMethodSymbol, assembleMethodSymbol,
CustomElement, CustomElement,
registerCustomElement, registerCustomElement,
} from "../../dom/customelement.mjs"; } from "../../dom/customelement.mjs";
import { findElementWithSelectorUpwards } from "../../dom/util.mjs"; import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
import { ThemeStyleSheet } from "../stylesheet/theme.mjs"; import {ThemeStyleSheet} from "../stylesheet/theme.mjs";
import { Datasource } from "./datasource.mjs"; import {Datasource} from "./datasource.mjs";
import { SpinnerStyleSheet } from "../stylesheet/spinner.mjs"; import {SpinnerStyleSheet} from "../stylesheet/spinner.mjs";
import { isString } from "../../types/is.mjs"; import {isString} from "../../types/is.mjs";
import { instanceSymbol } from "../../constants.mjs"; import {instanceSymbol} from "../../constants.mjs";
import "../form/select.mjs"; import "../form/select.mjs";
import "./datasource/dom.mjs"; import "./datasource/dom.mjs";
import "./datasource/rest.mjs"; import "./datasource/rest.mjs";
import "../form/popper.mjs"; import "../form/popper.mjs";
import "../form/context-error.mjs"; import "../form/context-error.mjs";
import { StatusStyleSheet } from "./stylesheet/status.mjs"; import {StatusStyleSheet} from "./stylesheet/status.mjs";
import {Formatter} from "../../text/formatter.mjs"; import {Formatter} from "../../text/formatter.mjs";
export { DatasourceStatus }; export {DatasourceStatus};
/** /**
* @private * @private
...@@ -59,86 +59,97 @@ const datasourceLinkedElementSymbol = Symbol("datasourceLinkedElement"); ...@@ -59,86 +59,97 @@ const datasourceLinkedElementSymbol = Symbol("datasourceLinkedElement");
* @summary The Status component is used to show the current status of a datasource. * @summary The Status component is used to show the current status of a datasource.
*/ */
class DatasourceStatus extends CustomElement { class DatasourceStatus extends CustomElement {
/** /**
*/ */
constructor() { constructor() {
super(); super();
} }
/** /**
* This method is called by the `instanceof` operator. * This method is called by the `instanceof` operator.
* @return {symbol} * @return {symbol}
*/ */
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/components/datatable/status@@instance"); return Symbol.for("@schukai/monster/components/datatable/status@@instance");
} }
/** /**
* To set the options via the HTML tag, the attribute `data-monster-options` must be used. * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
* *
* The individual configuration values can be found in the table. * The individual configuration values can be found in the table.
* *
* @property {Object} templates Template definitions * @property {Object} templates Template definitions
* @property {string} templates.main Main template * @property {string} templates.main Main template
* @property {Object} datasource Datasource configuration * @property {Object} datasource Datasource configuration
* @property {string} datasource.selector The selector of the datasource * @property {string} datasource.selector The selector of the datasource
* @property {Object} callbacks Callbacks * @property {Object} callbacks Callbacks
* @property {Function} callbacks.onError Callback function for error handling * @property {Function} callbacks.onError Callback function for error handling <code>function(message: string, event: Event): string</code>
* @property {Object} timeouts Timeouts * @property {Object} timeouts Timeouts
* @property {number} timeouts.message Timeout for the message * @property {number} timeouts.message Timeout for the message
* @property {Object} state State * @property {Object} state State
*/ */
get defaults() { get defaults() {
return Object.assign({}, super.defaults, { return Object.assign({}, super.defaults, {
templates: { templates: {
main: getTemplate(), main: getTemplate(),
}, },
datasource: { datasource: {
selector: null, selector: null,
}, },
callbacks: { callbacks: {
onError: null onError: null
}, },
timeouts: { timeouts: {
message: 4000, message: 4000,
}, },
state: { state: {
spinner: "hide", spinner: "hide",
}, },
}); });
} }
/** /**
* *
* @return {string} * @return {string}
*/ */
static getTag() { static getTag() {
return "monster-datasource-status"; return "monster-datasource-status";
} }
/** /**
* @private * @private
*/ */
[assembleMethodSymbol]() { [assembleMethodSymbol]() {
super[assembleMethodSymbol](); super[assembleMethodSymbol]();
initControlReferences.call(this); initControlReferences.call(this);
initEventHandler.call(this); initEventHandler.call(this);
} }
/** /**
* *
* @return [CSSStyleSheet] * @param message
*/ * @param timeout
static getCSSStyleSheet() { * @returns {DatasourceStatus}
return [StatusStyleSheet, SpinnerStyleSheet, ThemeStyleSheet]; */
} setErrorMessage(message, timeout) {
this[errorElementSymbol].setErrorMessage(message, timeout);
return this;
}
/**
*
* @return [CSSStyleSheet]
*/
static getCSSStyleSheet() {
return [StatusStyleSheet, SpinnerStyleSheet, ThemeStyleSheet];
}
} }
/** /**
...@@ -147,85 +158,85 @@ class DatasourceStatus extends CustomElement { ...@@ -147,85 +158,85 @@ class DatasourceStatus extends CustomElement {
* @throws {Error} no shadow-root is defined * @throws {Error} no shadow-root is defined
*/ */
function initControlReferences() { function initControlReferences() {
if (!this.shadowRoot) { if (!this.shadowRoot) {
throw new Error("no shadow-root is defined"); throw new Error("no shadow-root is defined");
} }
this[errorElementSymbol] = this.shadowRoot.querySelector( this[errorElementSymbol] = this.shadowRoot.querySelector(
"monster-context-error", "monster-context-error",
); );
} }
/** /**
* @private * @private
*/ */
function initEventHandler() { function initEventHandler() {
const selector = this.getOption("datasource.selector", ""); const selector = this.getOption("datasource.selector", "");
const self = this; const self = this;
if (isString(selector)) { if (isString(selector)) {
const element = findElementWithSelectorUpwards(this, selector); const element = findElementWithSelectorUpwards(this, selector);
if (element === null) { if (element === null) {
throw new Error("the selector must match exactly one element"); throw new Error("the selector must match exactly one element");
} }
if (!(element instanceof Datasource)) { if (!(element instanceof Datasource)) {
throw new TypeError("the element must be a datasource"); throw new TypeError("the element must be a datasource");
} }
let fadeOutTimer = null; let fadeOutTimer = null;
this[datasourceLinkedElementSymbol] = element; this[datasourceLinkedElementSymbol] = element;
element.addEventListener("monster-datasource-fetched", function () { element.addEventListener("monster-datasource-fetched", function () {
fadeOutTimer = setTimeout(() => { fadeOutTimer = setTimeout(() => {
self.setOption("state.spinner", "hide"); self.setOption("state.spinner", "hide");
}, 800); }, 800);
}); });
element.addEventListener("monster-datasource-fetch", function () { element.addEventListener("monster-datasource-fetch", function () {
if (fadeOutTimer) { if (fadeOutTimer) {
clearTimeout(fadeOutTimer); clearTimeout(fadeOutTimer);
fadeOutTimer = null; fadeOutTimer = null;
} }
self.setOption("state.spinner", "show"); self.setOption("state.spinner", "show");
}); });
element.addEventListener("monster-datasource-error", function (event) { element.addEventListener("monster-datasource-error", function (event) {
if (fadeOutTimer) { if (fadeOutTimer) {
clearTimeout(fadeOutTimer); clearTimeout(fadeOutTimer);
fadeOutTimer = null; fadeOutTimer = null;
} }
self.setOption("state.spinner", "hide"); self.setOption("state.spinner", "hide");
const timeout = self.getOption("timeouts.message", 4000); const timeout = self.getOption("timeouts.message", 4000);
let msg = "Cannot load data"; let msg = "Cannot load data";
try { try {
if (event.detail.error instanceof Error) { if (event.detail.error instanceof Error) {
msg = event.detail.error.message; msg = event.detail.error.message;
} else if (event.detail.error instanceof Object) { } else if (event.detail.error instanceof Object) {
msg = JSON.stringify(event.detail.error); msg = JSON.stringify(event.detail.error);
} else if (event.detail.error instanceof String) { } else if (event.detail.error instanceof String) {
msg = event.detail.error; msg = event.detail.error;
} else if (event.detail.error instanceof Number) { } else if (event.detail.error instanceof Number) {
msg = event.detail.error.toString(); msg = event.detail.error.toString();
} else { } else {
msg = event.detail.error; msg = event.detail.error;
} }
} catch (e) { } catch (e) {
} finally { } finally {
const callback = self.getOption("callbacks.onError", null); const callback = self.getOption("callbacks.onError", null);
if (callback) { if (callback) {
msg = callback(msg); callback.call(self, msg, event);
} } else {
self[errorElementSymbol].setErrorMessage(msg, timeout);
self[errorElementSymbol].setErrorMessage(msg, timeout); }
} }
}); });
} }
} }
/** /**
...@@ -233,13 +244,13 @@ function initEventHandler() { ...@@ -233,13 +244,13 @@ function initEventHandler() {
* @return {string} * @return {string}
*/ */
function getTemplate() { function getTemplate() {
// language=HTML // language=HTML
return ` return `
<div data-monster-role="control" part="control" <div data-monster-role="control" part="control"
data-monster-attributes="disabled path:disabled | if:true"> data-monster-attributes="disabled path:disabled | if:true">
<monster-context-error <monster-context-error
data-monster-option-classes-button="monster-theme-error-2 monster-theme-background-inherit"></monster-context-error> data-monster-option-classes-button="monster-theme-error-2 monster-theme-background-inherit"></monster-context-error>
<div class="monster-spinner" <div class="monster-spinner"
data-monster-attributes="data-monster-state-loader path:state.spinner"></div> data-monster-attributes="data-monster-state-loader path:state.spinner"></div>
</div> </div>
`; `;
......
...@@ -245,7 +245,7 @@ function fetchData(init, key, callback) { ...@@ -245,7 +245,7 @@ function fetchData(init, key, callback) {
if (body.length > 100) { if (body.length > 100) {
body = `${body.substring(0, 97)}...`; body = `${body.substring(0, 97)}...`;
} }
throw new DataFetchError( throw new DataFetchError(
getInternalLocalizationMessage( getInternalLocalizationMessage(
`i18n{the-response-does-not-contain-a-valid-json::actual=${body}}`, `i18n{the-response-does-not-contain-a-valid-json::actual=${body}}`,
...@@ -257,6 +257,7 @@ function fetchData(init, key, callback) { ...@@ -257,6 +257,7 @@ function fetchData(init, key, callback) {
if (callback && isFunction(callback)) { if (callback && isFunction(callback)) {
callback(obj); callback(obj);
} }
return response; return response;
}) })
.catch((e) => { .catch((e) => {
......
...@@ -32,8 +32,20 @@ class DataFetchError extends Error { ...@@ -32,8 +32,20 @@ class DataFetchError extends Error {
*/ */
constructor(message, response) { constructor(message, response) {
super(message); super(message);
let body = null
if (response instanceof Response) {
body = response.text();
}
if(!(body instanceof Promise)) {
body = Promise.resolve(body);
}
this[internalSymbol] = { this[internalSymbol] = {
response: response, response: response,
body : body
}; };
} }
...@@ -47,10 +59,17 @@ class DataFetchError extends Error { ...@@ -47,10 +59,17 @@ class DataFetchError extends Error {
); );
} }
/**
* @return {string|Object}
*/
getBody() {
return this[internalSymbol]?.["body"];
}
/** /**
* @return {Response} * @return {Response}
*/ */
getResponse() { getResponse() {
return this[internalSymbol]["response"]; return this[internalSymbol]?.["response"];
} }
} }
...@@ -28,7 +28,7 @@ function getInternalTranslations() { ...@@ -28,7 +28,7 @@ function getInternalTranslations() {
let locale = "en"; let locale = "en";
try { try {
let locale = getLocaleOfDocument(); locale = getLocaleOfDocument();
} catch (error) {} } catch (error) {}
let messages = {}; let messages = {};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment