homebridge-gira-client
Version:
Homebridge Plugin für Gira Homeserver 4 mit automatischer Geräteerkennung über IoT REST API
141 lines • 5.69 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorHandler = exports.GiraError = exports.ErrorCode = void 0;
exports.withErrorHandling = withErrorHandling;
exports.withRetry = withRetry;
var ErrorCode;
(function (ErrorCode) {
ErrorCode["CONNECTION_FAILED"] = "CONNECTION_FAILED";
ErrorCode["AUTHENTICATION_FAILED"] = "AUTHENTICATION_FAILED";
ErrorCode["DEVICE_NOT_FOUND"] = "DEVICE_NOT_FOUND";
ErrorCode["FUNCTION_NOT_FOUND"] = "FUNCTION_NOT_FOUND";
ErrorCode["INVALID_VALUE"] = "INVALID_VALUE";
ErrorCode["TIMEOUT"] = "TIMEOUT";
ErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
ErrorCode["PROTOCOL_ERROR"] = "PROTOCOL_ERROR";
ErrorCode["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR";
ErrorCode["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
})(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
class GiraError extends Error {
constructor(code, message, originalError, context) {
super(message);
this.code = code;
this.originalError = originalError;
this.context = context;
this.name = 'GiraError';
}
}
exports.GiraError = GiraError;
class ErrorHandler {
constructor(log) {
this.log = log;
this.errorCounts = new Map();
this.lastErrors = new Map();
}
handleError(error, context) {
let giraError;
if (error instanceof GiraError) {
giraError = error;
}
else {
giraError = this.categorizeError(error, context);
}
this.trackError(giraError);
this.logError(giraError);
return giraError;
}
categorizeError(error, context) {
const message = error.message.toLowerCase();
if (message.includes('connection') || message.includes('connect')) {
return new GiraError(ErrorCode.CONNECTION_FAILED, error.message, error, context);
}
if (message.includes('auth') || message.includes('login') || message.includes('credential')) {
return new GiraError(ErrorCode.AUTHENTICATION_FAILED, error.message, error, context);
}
if (message.includes('timeout')) {
return new GiraError(ErrorCode.TIMEOUT, error.message, error, context);
}
if (message.includes('network') || message.includes('dns') || message.includes('enotfound')) {
return new GiraError(ErrorCode.NETWORK_ERROR, error.message, error, context);
}
if (message.includes('device') && message.includes('not found')) {
return new GiraError(ErrorCode.DEVICE_NOT_FOUND, error.message, error, context);
}
if (message.includes('function') && message.includes('not found')) {
return new GiraError(ErrorCode.FUNCTION_NOT_FOUND, error.message, error, context);
}
if (message.includes('invalid') || message.includes('value')) {
return new GiraError(ErrorCode.INVALID_VALUE, error.message, error, context);
}
if (message.includes('protocol') || message.includes('websocket')) {
return new GiraError(ErrorCode.PROTOCOL_ERROR, error.message, error, context);
}
if (message.includes('config')) {
return new GiraError(ErrorCode.CONFIGURATION_ERROR, error.message, error, context);
}
return new GiraError(ErrorCode.UNKNOWN_ERROR, error.message, error, context);
}
trackError(error) {
const count = this.errorCounts.get(error.code) || 0;
this.errorCounts.set(error.code, count + 1);
this.lastErrors.set(error.code, new Date());
}
logError(error) {
const count = this.errorCounts.get(error.code) || 0;
const contextStr = error.context ? ` Context: ${JSON.stringify(error.context)}` : '';
this.log.error(`[${error.code}] ${error.message} (Count: ${count})${contextStr}`);
if (error.originalError && error.originalError.stack) {
this.log.debug(`Stack trace: ${error.originalError.stack}`);
}
}
getErrorCount(code) {
return this.errorCounts.get(code) || 0;
}
getLastError(code) {
return this.lastErrors.get(code);
}
clearErrorCounts() {
this.errorCounts.clear();
this.lastErrors.clear();
}
isRecurringError(code, threshold = 5, timeWindowMs = 300000) {
const count = this.errorCounts.get(code) || 0;
const lastError = this.lastErrors.get(code);
if (!lastError || count < threshold) {
return false;
}
const timeSinceLastError = Date.now() - lastError.getTime();
return timeSinceLastError < timeWindowMs;
}
}
exports.ErrorHandler = ErrorHandler;
function withErrorHandling(operation, errorHandler, context) {
return operation().catch(error => {
const giraError = errorHandler.handleError(error, context);
throw giraError;
});
}
function withRetry(operation, maxRetries = 3, delayMs = 1000, errorHandler) {
return new Promise((resolve, reject) => {
let attempts = 0;
const attempt = async () => {
try {
const result = await operation();
resolve(result);
}
catch (error) {
attempts++;
if (errorHandler) {
errorHandler.handleError(error instanceof Error ? error : new Error(String(error)));
}
if (attempts >= maxRetries) {
reject(error);
return;
}
setTimeout(attempt, delayMs * attempts);
}
};
attempt();
});
}
//# sourceMappingURL=error-handler.js.map