UNPKG

homebridge-homeconnect

Version:

A Homebridge plugin that connects Home Connect appliances to Apple HomeKit

118 lines 4.78 kB
// Homebridge plugin for Home Connect home appliances // Copyright © 2023-2025 Alexander Thoukydides import { STATUS_CODES } from 'http'; import { assertIsDefined, columns } from './utils.js'; import { checkers as apiCheckers } from './ti/api-types.js'; import { checkers as authCheckers } from './ti/api-auth-types.js'; // Base for reporting all Home Connect API errors export class APIError extends Error { constructor(request, response, message, options) { // Standard error object initialisation super(message); this.request = request; this.response = response; Error.captureStackTrace(this, APIError); this.name = 'Home Connect API Error'; if (options?.cause) this.errCause = options.cause; } } // API could not be authorised export class APIAuthorisationError extends APIError { constructor(request, response, message, options) { super(request, response, message, options); Error.captureStackTrace(this, APIAuthorisationError); this.name = 'Home Connect API Authorisation Error'; } } // API returned a non-success status code export class APIStatusCodeError extends APIError { constructor(request, response, text, options) { super(request, response, APIStatusCodeError.getMessage(response, text), options); this.text = text; Error.captureStackTrace(this, APIStatusCodeError); this.name = 'Home Connect Status Code Error'; } // Construct an error message from a response static getMessage(response, text) { const statusCode = response.statusCode; const statusCodeName = STATUS_CODES[statusCode]; const description = APIStatusCodeError.getBodyDescription(text) ?? 'No error message returned'; return `[${statusCode} ${statusCodeName}] ${description}`; } // Attempt to retrieve the error key get key() { return APIStatusCodeError.parseBody(this.text).key; } // Attempt to retrieve the error key get description() { return APIStatusCodeError.parseBody(this.text).description; } // Attempt to retrieve the error description get simpleMessage() { return APIStatusCodeError.getBodyDescription(this.text); } // Attempt to extract a useful description from the response body static getBodyDescription(text) { const { key, description } = APIStatusCodeError.parseBody(text); if (key) { return (description ? `${description} ` : '') + `[${key}]`; } else { return text.length ? text : undefined; } } // Attempt to parse the response body static parseBody(text) { try { const json = JSON.parse(text); if (apiCheckers.ErrorResponse.test(json)) { return { key: json.error.key, description: json.error.developerMessage ?? json.error.description ?? json.error.value }; } else if (authCheckers.AuthorisationError.test(json)) { return { key: json.error, description: json.error_description }; } } catch { /* empty */ } return {}; } } // API returned a response that failed checker validation export class APIValidationError extends APIError { constructor(request, response, validation, options) { super(request, response, APIValidationError.getMessage(validation), options); this.validation = validation; Error.captureStackTrace(this, APIValidationError); this.name = 'Home Connect API Validation Error'; } // Construct an error message from a checker validation error static getMessage(errors) { assertIsDefined(errors[0]); const description = `${errors[0].path} ${errors[0].message}`; return `Structure validation failed (${description})`; } } // API returned event stream that could not be parsed export class APIEventStreamError extends APIError { constructor(request, response, message, sse, options) { super(request, response, APIEventStreamError.getMessage(message, sse), options); this.sse = sse; Error.captureStackTrace(this, APIEventStreamError); this.name = 'Home Connect API Event Stream Error'; } // Construct an error message from a checker validation error static getMessage(description, sse) { const fields = Object.entries(sse).map(([name, value]) => [`${name}:`, value]); return [`Unable to parse ${description}:`, ...columns(fields)].join('\n'); } } //# sourceMappingURL=api-errors.js.map