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