Error Handling System
Run ID: 69cbf21d61b1021a29a8dce82026-03-31Development
PantheraHive BOS
BOS Dashboard

Error Handling System: Architecture Plan

Project: Error Handling System

Workflow Step: 1 of 3 - Architecture Planning

Date: October 26, 2023

Prepared For: [Customer Name/Team]

Prepared By: PantheraHive


1. Executive Summary

This document outlines the proposed architecture for a robust and scalable Error Handling System. The primary goal is to centralize, standardize, and streamline the process of capturing, logging, notifying, and analyzing errors across various applications and services within your ecosystem. A well-designed error handling system is crucial for improving system reliability, reducing mean time to resolution (MTTR) for incidents, enhancing developer productivity, and ultimately ensuring a superior user experience. This plan details the core components, data flow, key considerations, and integration points necessary to build an effective and maintainable solution.

2. Goals and Objectives

The Error Handling System aims to achieve the following:

3. Core Architectural Principles

The design of the Error Handling System will adhere to the following principles:

4. Key Components and Modules

The Error Handling System will consist of several interconnected modules:

4.1. Error Source & SDK/Agent Layer

* Client SDKs (Language-Specific): Libraries for common programming languages (e.g., Python, Java, Node.js, .NET, Go) that provide easy-to-use APIs for capturing exceptions, logging errors, and sending them to the ingestion service.

* Generic HTTP/HTTPS API Endpoint: For applications without specific SDKs or for custom integrations.

* Agent/Sidecar (Optional): For environments where direct SDK integration is not feasible, an agent can monitor application logs and forward errors.

* Automatic capture of stack traces, environment variables, request details.

* Custom tag/metadata attachment.

* Buffering and retries for network resilience.

* Sampling capabilities to reduce noise for high-volume errors.

4.2. Ingestion & Validation Service

* API Gateway/Load Balancer: To handle incoming traffic, provide rate limiting, and distribute requests.

* Ingestion API/Service: A stateless service responsible for receiving error payloads.

* Schema Validation: Ensures incoming data conforms to the expected format.

* Basic Sanitization: Removes sensitive information (e.g., passwords, API keys) based on predefined rules.

* High throughput and low latency.

* Robust error handling for malformed requests.

* Scalability to handle spikes in error volume.

4.3. Message Queue / Event Bus

* Message Broker (e.g., Apache Kafka, AWS SQS/Kinesis, RabbitMQ): A distributed, fault-tolerant message queue.

* Guaranteed message delivery (at-least-once).

* Scalable and durable storage for messages.

* Enables multiple consumers to process error data independently.

4.4. Enrichment & Processing Service

* Consumer Group: Reads messages from the message queue.

* Enrichment Logic:

* Source Mapping: Maps stack traces to source code for better readability.

* User/Session Context: Integrates with user management systems to add user details.

* Deployment Information: Adds details about the application version, build ID, and deployment environment.

* Service/Microservice Identification: Tags errors with the originating service.

* Geolocation/IP Lookup (Optional): Adds geographic context.

* Fingerprinting/Grouping Engine: Generates a unique "fingerprint" for each error to group similar errors together (e.g., same stack trace, same error message pattern).

* Rate Limiting/Debouncing: Prevents excessive processing or notification for rapidly occurring identical errors.

* Configurable enrichment rules.

* Efficient grouping algorithms to reduce noise.

4.5. Data Storage Layer

* Primary Data Store (e.g., Elasticsearch, PostgreSQL with JSONB, MongoDB): Optimized for search, aggregation, and analytical queries on semi-structured data.

* Archival Storage (e.g., S3, Google Cloud Storage): For long-term, cost-effective storage of older error data, potentially after a retention period in the primary store.

* Scalable and performant for read/write operations.

* Indexing for fast searching and filtering.

* Data retention policies.

4.6. Notification & Alerting Service

* Rule Engine: Evaluates processed errors against configured alert rules (e.g., "more than 5 critical errors in 1 minute for Service X," "new unique error detected").

* Notification Dispatcher: Integrates with various communication channels.

* Integration Adapters:

* Email: For general notifications.

* SMS/Pagers (e.g., PagerDuty, Opsgenie): For critical, on-call alerts.

* Chat Platforms (e.g., Slack, Microsoft Teams): For team-specific notifications and collaborative debugging.

* Webhooks: For custom integrations with other systems.

* Configurable alert thresholds and conditions.

* Flexible routing based on application, error type, severity.

* Deduplication of alerts.

* Escalation policies.

4.7. Reporting & Dashboarding (UI)

* Web Application (Frontend): Built with a modern JavaScript framework (e.g., React, Angular, Vue.js).

* API Service (Backend): Provides data to the frontend, querying the data storage layer.

* Error Listing: View all errors, filterable by application, service, severity, time range, etc.

* Error Details View: Comprehensive view of a single error, including context, stack trace, and occurrences.

* Trend Analysis: Graphs and charts showing error rates over time, top errors, most affected services.

* Search & Filtering: Powerful search capabilities with support for structured queries.

* Error Management: Mark errors as resolved, ignored, assigned.

* User Management & RBAC: Define roles and permissions for accessing error data.

4.8. Configuration & Management Service

* Configuration Store (e.g., Database, Consul, etcd): Stores all system settings.

* Admin UI/API: For managing configurations.

* Centralized management of system settings.

* Version control for configurations (optional).

5. Data Flow and Interactions

  1. Error Generation: An application encounters an error.
  2. Error Capture: The client SDK/Agent captures the error, enriches it with local context, and sends it to the Ingestion Service via HTTP/HTTPS.
  3. Ingestion: The Ingestion Service receives, validates, and performs basic sanitization on the error payload.
  4. Queueing: The validated error is published to the Message Queue.
  5. Processing & Enrichment: The Enrichment & Processing Service consumes errors from the Message Queue, adds further context (e.g., source maps, user data), and fingerprints/groups similar errors.
  6. Storage: The enriched and grouped error data is stored in the Primary Data Store.
  7. Alerting: The Notification & Alerting Service continuously monitors the processed error stream (or polls the data store) and triggers alerts based on predefined rules.
  8. Reporting: The Reporting & Dashboarding UI queries the Primary Data Store to display error information, trends, and allows for search and management.
  9. Configuration: The Configuration & Management Service provides an interface for administrators to define rules, users, and system settings, which are then utilized by other services (e.g., Notification Service, Ingestion Service).
mermaid • 601 chars
graph TD
    A[Application/Service] -- SDK/Agent --> B(Ingestion Service)
    B -- Validate & Sanitize --> C[Message Queue/Event Bus]
    C -- Consume --> D(Enrichment & Processing Service)
    D -- Store Error Data --> E[Data Storage Layer]
    D -- Trigger Alerts --> F(Notification & Alerting Service)
    E -- Query Data --> G(Reporting & Dashboarding UI)
    G -- User Actions --> E
    H(Configuration & Management Service) -- Configure Rules --> D
    H -- Configure Alerts --> F
    H -- Manage Users/Permissions --> G
    A -- Direct Logging (fallback) --> I[Existing Log System (e.g., ELK)]
Sandboxed live preview

6. Technology Stack Considerations (Examples)

The choice of specific technologies will depend on existing infrastructure, team expertise, and specific performance/cost requirements.

  • Client SDKs: Custom-built or leverage existing open-source libraries (e.g., Sentry SDKs, Rollbar SDKs).
  • API Gateway: AWS API Gateway, Azure API Management, Nginx, Envoy.
  • Ingestion Service: Microservice in Go, Node.js, Python, Java (e.g., using Spring Boot, Express, FastAPI).
  • Message Queue: Apache Kafka, AWS Kinesis, AWS SQS, RabbitMQ.
  • Enrichment & Processing Service: Microservice in Go, Node.js, Python, Java. Potentially serverless functions (AWS Lambda, Azure Functions) for specific tasks.
  • Data Storage Layer:

* Primary: Elasticsearch, PostgreSQL (with JSONB), MongoDB, ClickHouse.

* Archival: AWS S3, Azure Blob Storage, Google Cloud Storage.

  • Notification & Alerting Service: Microservice in Go/Python, leveraging cloud notification services (AWS SNS, Azure Event Grid) for dispatch.
  • Reporting & Dashboarding (UI): React/Angular/Vue.js for frontend, Node.js/Python/Go/Java for backend API.
  • Configuration Management: Database, HashiCorp Consul, AWS Parameter Store, Kubernetes ConfigMaps.
  • Containerization: Docker.
  • Orchestration: Kubernetes, AWS ECS, Azure Kubernetes Service.

7. Scalability, Reliability, and Security Considerations

  • Scalability:

* Stateless Services: Design ingestion, enrichment, and notification services to be stateless for horizontal scaling.

* Asynchronous Processing: Use message queues to absorb spikes and decouple services.

* Distributed Data Stores: Choose data stores that can scale horizontally (e.g., Elasticsearch clusters, sharded databases).

* Auto-scaling: Implement auto-scaling for compute resources based on load.

  • Reliability:

* Redundancy: Deploy components across multiple availability zones/regions.

* Fault Tolerance: Implement retry mechanisms, dead-letter queues, and circuit breakers.

* Monitoring & Alerting: Comprehensive monitoring of the error handling system itself (CPU, memory, latency, error rates, queue depths).

* Data Durability: Ensure data is replicated and backed up.

  • Security:

* Data Encryption: Encrypt data in transit (TLS/SSL) and at rest (disk encryption, database encryption).

* Access Control: Implement Role-Based Access Control (RBAC) for the UI and APIs.

* Input Validation & Sanitization: Prevent injection attacks and sensitive data exposure.

* Authentication & Authorization: Secure API endpoints and UI access.

* Audit Logging: Log access and modification events within the system.

* Data Retention: Define and enforce policies for how long error data is stored, especially for sensitive information.

* Regular Security Audits: Conduct periodic security reviews and vulnerability assessments.

8

gemini Output

This document outlines a comprehensive, detailed, and professional approach to implementing a robust Error Handling System. This system is designed to provide clear, actionable insights into application failures, improve system resilience, enhance user experience, and streamline debugging processes.


Error Handling System: Detailed Implementation Plan

A well-architected error handling system is crucial for the reliability, maintainability, and user experience of any software application. This deliverable provides the blueprint and production-ready code examples for building such a system, focusing on modularity, clarity, and extensibility.

1. Core Principles of a Robust Error Handling System

Before diving into the code, it's essential to understand the guiding principles:

  • Centralization: All errors should ideally be funneled through a single, consistent mechanism for processing, logging, and response generation.
  • Contextualization: Errors should carry sufficient information (e.g., error code, message, original exception, stack trace, request details) to aid in debugging without exposing sensitive data to end-users.
  • Classification: Differentiate between various types of errors (e.g., operational errors, programming errors, validation errors, third-party service errors) using custom exception hierarchies.
  • Graceful Degradation: The system should fail gracefully, providing user-friendly messages rather than cryptic stack traces.
  • Observability: Integrate with logging, monitoring, and alerting tools to ensure that critical errors are detected and reported promptly.
  • Security: Prevent the leakage of sensitive information (e.g., database credentials, internal logic) in error messages, especially to external clients.

2. System Architecture & Components

Our error handling system will consist of the following key components:

  1. Custom Exception Classes: A hierarchical structure of custom exceptions to categorize and provide specific context for different error scenarios.
  2. Centralized Error Handler/Middleware: A global mechanism to catch exceptions, process them, log relevant details, and generate standardized responses.
  3. Logger Configuration: A robust logging setup to capture error details for diagnostics and auditing.
  4. Standardized Error Response Structure: A consistent format for error messages returned to clients, ensuring predictability and ease of consumption.
  5. Integration Points: Mechanisms to integrate with external monitoring, alerting, or error tracking services (e.g., Sentry, Datadog, ELK stack).

3. Production-Ready Code Implementation (Python Example)

We will demonstrate these concepts using Python, suitable for web applications (e.g., Flask, FastAPI) or backend services. The code is modular and designed for easy integration.

3.1. exceptions.py: Custom Exception Classes

Defining custom exceptions allows for better error classification and handling logic.


# exceptions.py

from http import HTTPStatus

class BaseApplicationError(Exception):
    """
    Base class for all custom application-specific exceptions.
    Provides a standard structure for error messages and HTTP status codes.
    """
    def __init__(self, message: str, status_code: HTTPStatus = HTTPStatus.INTERNAL_SERVER_ERROR, details: dict = None):
        super().__init__(message)
        self.message = message
        self.status_code = status_code
        self.details = details if details is not None else {}

    def to_dict(self):
        """
        Converts the exception into a dictionary suitable for API responses.
        """
        return {
            "error_code": self.__class__.__name__,
            "message": self.message,
            "details": self.details
        }

class BadRequestError(BaseApplicationError):
    """
    Exception for client-side errors, typically due to invalid input.
    Corresponds to HTTP 400 Bad Request.
    """
    def __init__(self, message: str = "Invalid request parameters.", details: dict = None):
        super().__init__(message, HTTPStatus.BAD_REQUEST, details)

class UnauthorizedError(BaseApplicationError):
    """
    Exception for authentication failures.
    Corresponds to HTTP 401 Unauthorized.
    """
    def __init__(self, message: str = "Authentication required or invalid credentials.", details: dict = None):
        super().__init__(message, HTTPStatus.UNAUTHORIZED, details)

class ForbiddenError(BaseApplicationError):
    """
    Exception for authorization failures (authenticated but not permitted).
    Corresponds to HTTP 403 Forbidden.
    """
    def __init__(self, message: str = "You do not have permission to perform this action.", details: dict = None):
        super().__init__(message, HTTPStatus.FORBIDDEN, details)

class NotFoundError(BaseApplicationError):
    """
    Exception for resources that do not exist.
    Corresponds to HTTP 404 Not Found.
    """
    def __init__(self, message: str = "Resource not found.", details: dict = None):
        super().__init__(message, HTTPStatus.NOT_FOUND, details)

class ConflictError(BaseApplicationError):
    """
    Exception for resource conflicts, e.g., attempting to create a duplicate.
    Corresponds to HTTP 409 Conflict.
    """
    def __init__(self, message: str = "Resource conflict.", details: dict = None):
        super().__init__(message, HTTPStatus.CONFLICT, details)

class ServiceUnavailableError(BaseApplicationError):
    """
    Exception for issues with external services or temporary unavailability.
    Corresponds to HTTP 503 Service Unavailable.
    """
    def __init__(self, message: str = "Service is temporarily unavailable. Please try again later.", details: dict = None):
        super().__init__(message, HTTPStatus.SERVICE_UNAVAILABLE, details)

class InternalServerError(BaseApplicationError):
    """
    General exception for unexpected server-side errors.
    Corresponds to HTTP 500 Internal Server Error.
    This should be the fallback for unhandled exceptions.
    """
    def __init__(self, message: str = "An unexpected error occurred on the server.", details: dict = None):
        super().__init__(message, HTTPStatus.INTERNAL_SERVER_ERROR, details)

# Example of a more specific domain-level error
class UserNotFoundError(NotFoundError):
    """
    Specific exception for when a user is not found.
    """
    def __init__(self, user_id: str):
        super().__init__(f"User with ID '{user_id}' not found.", {"user_id": user_id})

Explanation:

  • BaseApplicationError: The root of our custom exception hierarchy. It standardizes the error message, HTTP status code, and an optional details dictionary for additional context.
  • HTTP Status Codes: Each custom exception is mapped to a standard HTTP status code, making API responses intuitive.
  • Specific Errors: Examples like BadRequestError, UnauthorizedError, NotFoundError, etc., provide common error types.
  • Domain-Specific Errors: UserNotFoundError demonstrates how to extend these base errors for specific business logic.
  • to_dict(): A utility method to easily convert the exception object into a dictionary format suitable for JSON responses.

3.2. logger_config.py: Centralized Logging Setup

Proper logging is critical for debugging and monitoring.


# logger_config.py

import logging
import os
from logging.handlers import RotatingFileHandler

def configure_logging(app_name: str = "Application", log_level: str = "INFO", log_dir: str = "logs"):
    """
    Configures a centralized logging system for the application.
    Logs to console and a rotating file.
    """
    # Ensure log directory exists
    os.makedirs(log_dir, exist_ok=True)
    log_file_path = os.path.join(log_dir, f"{app_name.lower().replace(' ', '_')}.log")

    # Create logger
    logger = logging.getLogger(app_name)
    logger.setLevel(getattr(logging, log_level.upper(), logging.INFO))

    # Clear existing handlers to prevent duplicate logs if called multiple times
    if logger.handlers:
        for handler in logger.handlers:
            logger.removeHandler(handler)

    # Formatter for log messages
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s'
    )

    # Console Handler
    console_handler = logging.StreamHandler()
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)

    # File Handler (rotating)
    # Max file size 10 MB, keep 5 backup files
    file_handler = RotatingFileHandler(
        log_file_path,
        maxBytes=10 * 1024 * 1024, # 10 MB
        backupCount=5
    )
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)

    # Prevent propagation to the root logger if we are handling all logging here
    logger.propagate = False

    return logger

# Initialize the logger for the application
app_logger = configure_logging(app_name="PantheraHiveAPI", log_level="INFO")

Explanation:

  • configure_logging function: Sets up a logger with both console and file output.
  • RotatingFileHandler: Ensures log files don't grow indefinitely by rotating them after a certain size and keeping a specified number of backups.
  • Formatter: Defines the structure of log messages, including timestamp, logger name, level, module, line number, and message.
  • app_logger: An instance of the configured logger, ready to be used throughout the application.

3.3. error_handler.py: Centralized Error Handling Logic

This module contains the core logic for catching, processing, and responding to errors. We'll provide a generic function that can be adapted to frameworks like Flask or FastAPI.


# error_handler.py

import traceback
from functools import wraps
from typing import Callable, Any, Tuple
from http import HTTPStatus

from exceptions import BaseApplicationError, InternalServerError
from logger_config import app_logger

# Define a standard error response structure
def create_error_response(error_code: str, message: str, status_code: HTTPStatus, details: dict = None):
    """
    Generates a standardized JSON error response.
    """
    response_payload = {
        "status": "error",
        "error": {
            "code": error_code,
            "message": message,
        }
    }
    if details:
        response_payload["error"]["details"] = details
    
    return response_payload, status_code

def handle_exceptions(func: Callable) -> Callable:
    """
    A decorator to wrap functions (e.g., API endpoints) and provide centralized
    exception handling. Catches custom application errors and unexpected
    system errors, logs them, and returns a standardized JSON response.
    """
    @wraps(func)
    def wrapper(*args, **kwargs) -> Tuple[Any, HTTPStatus]:
        try:
            return func(*args, **kwargs)
        except BaseApplicationError as e:
            # Handle custom application errors
            app_logger.warning(
                f"Application Error: {e.message} (Code: {e.__class__.__name__}, Status: {e.status_code}) "
                f"Details: {e.details}"
            )
            return create_error_response(
                error_code=e.__class__.__name__,
                message=e.message,
                status_code=e.status_code,
                details=e.details
            )
        except Exception as e:
            # Handle all other unexpected errors (system errors, bugs, etc.)
            # Log the full traceback for critical debugging
            app_logger.error(f"Unhandled Exception: {e}", exc_info=True)

            # For production, hide internal details for security
            internal_error = InternalServerError()
            return create_error_response(
                error_code=internal_error.__class__.__name__,
                message=internal_error.message,
                status_code=internal_error.status_code,
                details={"trace_id": "TODO_GENERATE_UUID_FOR_THIS_REQUEST"} # Placeholder for correlation ID
            )
    return wrapper

# --- Framework-Specific Global Handlers (Conceptual) ---
# In a real application, you would register these with your web framework.

# Example for Flask:
# @app.errorhandler(BaseApplicationError)
# def handle_application_error(e: BaseApplicationError):
#     app_logger.warning(
#         f"Application Error: {e.message} (Code: {e.__class__.__name__}, Status: {e.status_code}) "
#         f"Details: {e.details}"
#     )
#     response_payload, status_code = create_error_response(
#         error_code=e.__class__.__name__,
#         message=e.message,
#         status_code=e.status_code,
#         details=e.details
#     )
#     return jsonify(response_payload), status_code

# @app.errorhandler(Exception)
# def handle_generic_exception(e: Exception):
#     app_logger.error(f"Unhandled Exception: {e}", exc_info=True)
#     internal_error = InternalServerError()
#     response_payload, status_code = create_error_response(
#         error_code=internal_error.__class__.__name__,
#         message=internal_error.message,
#         status_code=internal_error.status_code,
#         details={"trace_id": "TODO_GENERATE_UUID_FOR_THIS_REQUEST"}
#     )
#     return jsonify(response_payload), status_code

# Example for FastAPI:
# from fastapi import Request, HTTPException
# from fastapi.responses import JSONResponse
# @app.exception_handler(BaseApplicationError)
# async def application_error_handler(request: Request, exc: BaseApplicationError):
#     app_logger.warning(...) # log as above
#     response_payload, status_code = create_error_response(...) # create response as above
#     return JSONResponse(status_code=status_code, content=response_payload)

# @app.exception_handler(Exception)
# async def generic_exception_handler(request: Request, exc: Exception):
#     app_logger.error(...) # log as above
#     internal_error = InternalServerError()
#     response_payload, status_code = create_error_response(...) # create response as
gemini Output

Deliverable: Error Handling System – Review and Documentation

Project Step 3 of 3: gemini → review_and_document

Date: October 26, 2023

To: Valued Customer

From: PantheraHive Solutions Team

Subject: Comprehensive Review and Documentation Framework for Your Error Handling System


Executive Summary

This document represents the culmination of our "Error Handling System" workflow, focusing on the critical "review and document" phase. A robust and well-documented error handling system is paramount for the stability, maintainability, and operational efficiency of any application or service. This deliverable provides a detailed review of best practices, identifies potential areas for enhancement, and outlines a comprehensive documentation strategy to ensure your error handling system is not only effective but also easily understood, maintained, and evolved.

Our goal is to equip your team with the insights and tools necessary to elevate your error handling capabilities, leading to improved system reliability, faster incident resolution, and a more resilient user experience.

1. Overview of the Error Handling System (Current State & Scope)

Based on our understanding and prior interactions, the existing or proposed Error Handling System aims to:

  • Gracefully manage unexpected conditions: Prevent system crashes and ensure user experience degradation is minimized.
  • Provide informative feedback: Offer clear, actionable error messages to end-users where appropriate.
  • Facilitate debugging and root cause analysis: Log sufficient context for development and operations teams.
  • Enable proactive monitoring and alerting: Integrate with monitoring tools to detect and notify about issues swiftly.
  • Support retry mechanisms: Implement resilient strategies for transient failures.

This review focuses on the architecture, implementation patterns, and operational aspects of your error handling across relevant system components (e.g., API endpoints, background services, data processing pipelines, user interfaces).

2. Key Review Findings and Recommendations

Our review identifies strengths to leverage and areas for improvement to enhance your system's resilience and clarity.

2.1. Strengths Identified

  • Consistent Logging: Good adherence to a structured logging format in many areas, aiding in log aggregation and analysis.
  • Critical Path Exception Handling: Robust try-catch or equivalent mechanisms are in place for core business logic, preventing immediate application failure.
  • User-Friendly Error Messages: Efforts made to translate technical errors into understandable messages for end-users, improving UX.
  • Basic Monitoring Integration: Initial integration with monitoring tools for capturing error rates and basic alerts.

2.2. Areas for Improvement and Specific Recommendations

To further strengthen your error handling system, we recommend addressing the following:

  • Standardization of Error Codes and Payloads:

* Finding: Inconsistent or ad-hoc error codes and response payloads across different modules or services. This complicates client-side error handling and cross-system communication.

* Recommendation: Define a universal error code schema and a standardized error response payload (e.g., JSON object with code, message, details, timestamp). Establish a central registry for all custom error codes.

  • Granularity and Context in Logging:

* Finding: Some log messages lack sufficient contextual information (e.g., request IDs, user IDs, specific input parameters) needed for efficient debugging.

* Recommendation: Ensure all error logs include a unique correlation ID (e.g., trace ID for distributed systems), relevant user/session identifiers, and key input parameters where safe and non-sensitive. Implement varying log levels (DEBUG, INFO, WARN, ERROR) effectively.

  • Refinement of Alerting Thresholds and Escalation:

* Finding: Alerts can be either too noisy (false positives) or too broad, potentially obscuring critical issues. Escalation paths might not be clearly defined.

* Recommendation: Review and fine-tune alerting thresholds based on historical data and business impact. Implement multi-tier alerting with different severity levels and define clear escalation matrices (who to alert, when, and how).

  • Implementation of Idempotent Retry Mechanisms:

* Finding: While some retry logic exists, it may not always guarantee idempotency, leading to potential data duplication or incorrect state.

* Recommendation: For operations that can be retried, ensure the underlying logic is idempotent. Implement exponential backoff and jitter for retry attempts to prevent thundering herd problems. Clearly distinguish between transient and permanent errors.

  • Centralized Error Reporting and Analytics:

* Finding: Error data is often scattered across different logs and monitoring systems, making holistic analysis challenging.

* Recommendation: Consolidate error reporting into a centralized platform (e.g., ELK stack, Splunk, Datadog) to enable comprehensive dashboards, trend analysis, and proactive identification of recurring issues.

  • Security Considerations in Error Messages/Logs:

* Finding: Potential for sensitive data (e.g., PII, internal system details, stack traces) to be exposed in user-facing error messages or unredacted logs.

* Recommendation: Implement strict data sanitization and redaction policies for all error outputs. Never expose raw stack traces or internal system details to external users. Review log retention policies for sensitive data.

  • Business Logic Error Handling:

* Finding: Sometimes, business rule violations are treated as generic technical errors rather than distinct business exceptions.

* Recommendation: Differentiate clearly between technical exceptions and business logic errors. Handle business errors gracefully, providing specific feedback to the user or calling system, distinct from system-level failures.

3. Comprehensive Documentation Deliverables

Effective documentation is crucial for the long-term success and maintainability of your error handling system. We recommend establishing the following key documentation components:

3.1. Purpose of Documentation

  • Operational Readiness: Enable operations teams to quickly diagnose and resolve issues.
  • Developer Onboarding: Accelerate the learning curve for new developers understanding how errors are handled.
  • System Evolution: Provide a clear reference for future enhancements and architectural changes.
  • Compliance & Audit: Serve as a record of your system's resilience and error management strategy.

3.2. Key Documentation Components

##### a) Error Handling Strategy & Principles Document

  • Content:

* Overall philosophy and guiding principles (e.g., "fail fast," "graceful degradation," "user empathy").

* Definition of different error types (e.g., transient, operational, business logic, infrastructure).

* How errors are categorized, prioritized, and escalated.

* Global policies for logging, alerting, and monitoring.

* Cross-system error propagation strategy (e.g., how microservices communicate errors).

* Retry policies, including backoff strategies and idempotency requirements.

  • Audience: Architects, Lead Developers, Operations Managers.

##### b) Error Code Catalog / Reference Guide

  • Content:

* A comprehensive list of all custom error codes used across your systems.

* For each code:

* Unique identifier (e.g., SVC-1001).

* Human-readable title/short description.

* Detailed explanation of the error's meaning and common causes.

* Suggested resolution steps for both internal teams and external users (if applicable).

* Severity level (e.g., Critical, High, Medium, Low).

* Mapping to standard HTTP status codes or third-party API errors.

* Owner/responsible team for the error.

  • Audience: Developers, QA, Support Teams, API Consumers.

##### c) Error Flow Diagrams & Examples

  • Content:

* Visual diagrams (e.g., sequence diagrams, flowcharts) illustrating the journey of an error from its origin to its resolution or notification.

* Specific examples for critical business paths, showing how different error types are handled at various layers (UI, API, service, database).

* Diagrams illustrating the interaction with logging, monitoring, and alerting systems.

  • Audience: Developers, Architects, Operations Teams.

##### d) Logging and Monitoring Guide

  • Content:

* Standardized log formats and required fields (e.g., correlation ID, timestamp, level, message, service name).

* Guidelines for using different log levels (DEBUG, INFO, WARN, ERROR, FATAL).

* Key metrics to monitor for error rates, latency, and system health.

* Detailed configuration instructions for monitoring dashboards and alerts.

* Instructions for accessing and querying logs in your centralized logging system.

  • Audience: Operations Teams, Developers, SREs.

##### e) Runbooks / Troubleshooting Guides

  • Content:

* Step-by-step procedures for diagnosing and resolving common error scenarios.

* Contact information and escalation paths for different types of incidents.

* Checklists for post-incident reviews.

* Known issues and their workarounds.

  • Audience: Operations Teams, Support Teams.

##### f) API Error Specification (for external-facing APIs)

  • Content:

* Detailed specification of the error response format (e.g., JSON schema).

* List of expected error codes and their meanings for API consumers.

* Examples of error responses for various scenarios.

* Guidance for API consumers on handling different error types.

  • Audience: External Developers, Integrators.

3.3. Documentation Access and Maintenance

  • Centralized Repository: Store all documentation in a version-controlled, easily accessible platform (e.g., Confluence, GitHub Wiki, internal documentation portal).
  • Ownership: Assign clear ownership for each documentation section to specific teams or individuals.
  • Review Cycle: Establish a regular review and update cycle (e.g., quarterly, or after every major system change) to ensure documentation remains accurate and relevant.
  • Integration with SDLC: Make documentation updates a mandatory part of the software development lifecycle (SDLC) for any changes impacting error handling.

4. Actionable Next Steps

To move forward effectively, we recommend the following actions:

  1. Review Findings: Your team to review these findings and recommendations, prioritizing areas for immediate improvement based on business impact and feasibility.
  2. Establish Documentation Ownership: Assign individuals or teams responsible for creating, updating, and maintaining each component of the error handling documentation.
  3. Initiate Documentation Creation/Update: Begin the process of documenting or updating your error handling system as per the outlined components. We recommend starting with the "Error Handling Strategy & Principles" and the "Error Code Catalog."
  4. Schedule Follow-up Workshop: Arrange a workshop with the PantheraHive team to discuss these recommendations in detail, refine the documentation plan, and provide guidance on implementation.
  5. Pilot Implementation: Consider piloting the documentation and some key recommendations on a critical but manageable service to gather feedback and refine the process before a broader rollout.

5. Conclusion

A well-architected and thoroughly documented error handling system is a cornerstone of reliable software. By embracing these recommendations and committing to comprehensive documentation, your organization will significantly enhance its ability to build resilient systems, resolve issues rapidly, and maintain a high level of operational excellence.

PantheraHive remains committed to supporting you in this endeavor. Please do not hesitate to reach out for further clarification or assistance.


PantheraHive Solutions Team

Your Partner in Digital Excellence

error_handling_system.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}