Error Handling System
Run ID: 69bcaa6c77c0421c0bf4a63f2026-03-29Development
PantheraHive BOS
BOS Dashboard

Error Handling System - Step 1: Generate (JavaScript & Test Error Types)

This document outlines a comprehensive approach to implementing an Error Handling System in JavaScript, with a specific focus on "Test Error Types." It provides core principles, actionable recommendations, and practical code examples to ensure robust error management, particularly within a testing context.


1. Introduction to Error Handling in JavaScript for Testing

Robust error handling is a cornerstone of reliable software. In JavaScript, an effective error handling system ensures application stability, provides clear feedback for debugging, and improves the user experience. When integrated with a testing strategy, it allows developers to:

The concept of "Test Error Types" refers to both the intrinsic errors that occur during the execution of tests (e.g., assertion failures, setup/teardown issues) and custom error types defined within the application code that are specifically designed to be tested for and handled.


2. Core JavaScript Error Handling Mechanisms

JavaScript provides fundamental constructs for managing errors:

* try: Encloses the code that might throw an error.

* catch (error): Executes if an error occurs in the try block, receiving the Error object.

* finally: Executes regardless of whether an error occurred or was caught, often used for cleanup.

* The base Error object provides name (e.g., "Error", "TypeError") and message properties.

* Built-in subtypes include TypeError, ReferenceError, RangeError, SyntaxError, URIError, and EvalError. These are crucial for distinguishing error causes.

* Promises: Errors in Promises are caught using .catch() or as the second argument in .then(). Uncaught Promise rejections can be handled globally with unhandledrejection event.

* async/await: Errors within async functions can be caught using try...catch blocks, making asynchronous error handling syntactically similar to synchronous handling.


3. Defining and Handling "Test Error Types"

"Test Error Types" encompass a range of scenarios where errors are relevant to or occur within the testing process.

3.1. Understanding "Test Error Types"

  1. Assertion Errors: These are the most common "test errors." They occur when an assertion (e.g., expect(a).toBe(b)) fails, indicating that the actual output doesn't match the expected output. Testing frameworks (Jest, Mocha, etc.) typically throw specific assertion error types (e.g., JestAssertionError).
  2. Setup/Teardown Errors: Errors occurring in beforeAll, beforeEach, afterAll, afterEach hooks. These can prevent tests from running or leave the environment in an inconsistent state.
  3. Mocking/Stubbing Errors: Issues arising from incorrect mock configurations, unavailable dependencies, or misbehaving stubs.
  4. Custom Application Errors: Errors defined within your application code (e.g., ValidationError, NetworkError, InsufficientPermissionsError) that you explicitly want to test how your system responds to. This is a critical aspect of integration and unit testing.
  5. Environment/Configuration Errors: Problems with test runner setup, environment variables, or external service dependencies that prevent tests from executing correctly.

3.2. Creating Custom Error Types (for Application Code)

Custom error types enhance clarity and enable more granular error handling and testing. They should inherit from the built-in Error class to gain standard properties like stack.

Example: Custom ValidationError

text • 6,042 chars
#### 3.4. Strategies for Test-Specific Error Handling

*   **Isolate Test Failures:** Each test should ideally fail independently. If a setup error affects multiple tests, ensure it's reported clearly at the suite level.
*   **Clear Error Messages:** Ensure custom errors and assertion messages are descriptive. This significantly reduces debugging time.
*   **Error Logging in Tests:** While tests usually fail immediately on an error, sometimes logging additional context within a `catch` block in a test utility or setup hook can be invaluable for diagnosing complex issues.
*   **Global Error Handlers for Tests:** Be cautious with global error handlers (`process.on('unhandledRejection')`, `process.on('uncaughtException')`) in a testing environment. While useful for debugging, they can sometimes mask specific test failures or interfere with how testing frameworks report errors. Use them judiciously for reporting unexpected errors, not for catching expected test failures.

---

### 4. Actionable Recommendations for a Robust Error Handling System

#### 4.1. Standardize Error Types

*   **Define a clear hierarchy:** All custom errors should extend a base `ApplicationError` or `Error`.
*   **Categorize errors:** Group errors by their domain (e.g., `AuthError`, `DatabaseError`, `ValidationError`, `NetworkError`).
*   **Include relevant metadata:** Custom errors should carry context (e.g., `statusCode`, `errorCode`, `details`, `resourceId`) to aid debugging and automated handling.

#### 4.2. Centralize Error Handling Logic

*   **API Middleware:** For web applications, implement global error handling middleware that catches errors, logs them, and sends standardized error responses.
*   **Service Layer:** Within your application's service or business logic layer, use `try...catch` to handle specific errors, transform them if necessary (e.g., re-throw a more abstract error), or perform recovery actions.
*   **Asynchronous Wrappers:** Create utility functions to wrap asynchronous operations (`Promise.resolve().catch()`, `async/await try...catch`) to ensure consistent error handling.

#### 4.3. Use Custom Errors Judiciously

*   **Avoid over-engineering:** Don't create a custom error for every single failure scenario. Use built-in errors where appropriate (e.g., `TypeError` for invalid input types).
*   **Focus on actionable errors:** Custom errors are most valuable when they convey specific information that can be used to recover, retry, or inform the user/developer.

#### 4.4. Implement Robust Logging

*   **Structured Logging:** Use a logging library (e.g., Winston, Pino) to log errors with structured data (JSON) for easier analysis and querying.
*   **Contextual Information:** Always include request IDs, user IDs, function names, and any relevant state when logging errors.
*   **Error Reporting Tools:** Integrate with external error monitoring services (e.g., Sentry, Bugsnag) to aggregate, track, and alert on production errors.

#### 4.5. Integrate with Testing Frameworks Effectively

*   **Utilize `expect().toThrow()`/`rejects.toThrow()`:** These are your primary tools for testing error conditions.
*   **Snapshot Testing for Errors:** Consider using snapshot testing for error objects (especially custom ones) to ensure their structure and content remain consistent over time.
*   **Test Error Recovery:** Write tests that verify not only that an error is thrown, but also that the system can gracefully recover or handle the error without crashing.

#### 4.6. Ensure Comprehensive Error Testing

*   **Positive Test Cases:** Verify that code works correctly when no errors occur.
*   **Negative Test Cases:** Verify that code correctly throws and handles expected errors under various failure conditions (e.g., invalid input, missing resources, network failures, permission denied).
*   **Edge Cases:** Test boundary conditions and unusual inputs that might trigger errors.
*   **Asynchronous Error Scenarios:** Explicitly test `Promise.reject` and `async/await` error paths.

---

### 5. Structured Data & Code Examples

This section provides a summary of key concepts and code snippets.

**Table 1: Key JavaScript Error Handling Constructs**

| Construct                | Description                                                                  | Example                                                              |
| :----------------------- | :--------------------------------------------------------------------------- | :------------------------------------------------------------------- |
| `try...catch...finally`  | Manages synchronous errors, allowing recovery and cleanup.                   | `try { /* code */ } catch (e) { /* handle */ } finally { /* cleanup */ }` |
| `throw`                  | Explicitly raises an error.                                                  | `throw new Error('Something went wrong');`                           |
| `Error` Object           | Base error class with `name` and `message`.                                  | `new TypeError('Invalid type');`                                     |
| Custom Error Classes     | Extend `Error` for domain-specific error types.                              | `class MyError extends Error { ... }`                                |
| `Promise.catch()`        | Handles rejections in Promises.                                              | `fetchData().catch(e => console.error(e));`                          |
| `async/await` `try/catch` | Handles asynchronous errors in a synchronous-like manner.                   | `async function() { try { await op(); } catch (e) { /* handle */ } }` |
| `expect().toThrow()`     | Jest/Mocha utility for testing synchronous errors.                           | `expect(() => func()).toThrow(MyError);`                             |
| `expect().rejects.toThrow()` | Jest utility for testing asynchronous errors (Promise rejections).           | `await expect(asyncFunc()).rejects.toThrow('Error message');`        |

**Code Example 1: Custom Error Definition**

Sandboxed live preview

This comprehensive output provides a solid foundation for building a robust error handling system in JavaScript, with specific guidance tailored to "Test Error Types" to enhance the reliability and testability of your applications.

Step 2: projectmanager

Comprehensive Error Handling System for JavaScript

This document outlines a robust error handling system for JavaScript applications, focusing on best practices, common scenarios, and specific recommendations for managing various error types, including "Test Error Types" as requested.

1. Introduction: The Imperative of Error Handling

Effective error handling is crucial for building resilient, reliable, and user-friendly JavaScript applications. It ensures that applications can gracefully recover from unexpected issues, provide meaningful feedback to users, prevent data corruption, and facilitate efficient debugging. A well-designed error handling system enhances stability, improves user experience, and reduces maintenance overhead.

2. Core JavaScript Error Handling Mechanisms

JavaScript provides fundamental constructs for managing errors.

2.1. try...catch...finally Statement

The cornerstone of synchronous error handling.

  • try block: Contains the code that might throw an error.
  • catch block: Executes if an error occurs within the try block. It receives the error object as an argument.
  • finally block: Executes after both try and catch blocks, regardless of whether an error occurred or not. It's ideal for cleanup operations (e.g., closing file handles, releasing resources).

Example:


try {
    // Code that might throw an error
    const result = dangerousOperation();
    console.log("Operation successful:", result);
} catch (error) {
    // Code to handle the error
    console.error("An error occurred:", error.message);
    // Log the full error for debugging
    logErrorToServer(error);
    // Provide user feedback
    displayErrorMessage("Something went wrong. Please try again.");
} finally {
    // Code that always executes (e.g., cleanup)
    console.log("Operation attempt finished.");
    releaseResources();
}

function dangerousOperation() {
    // Simulate an error
    if (Math.random() > 0.5) {
        throw new Error("Simulated failure in dangerousOperation!");
    }
    return "Data processed successfully.";
}

function logErrorToServer(error) {
    // Placeholder for actual logging mechanism (e.g., API call to a logging service)
    console.warn("Logging error to server:", {
        message: error.message,
        stack: error.stack,
        name: error.name
    });
}

function displayErrorMessage(message) {
    // Placeholder for displaying a message to the user (e.g., UI notification)
    alert(message);
}

function releaseResources() {
    // Placeholder for resource cleanup
    console.log("Resources released.");
}

2.2. throw Statement

The throw statement is used to generate a custom error or re-throw an caught error. You can throw any JavaScript value, but it's best practice to throw Error objects or instances of custom error classes.

Example:


function validateInput(value) {
    if (typeof value !== 'number' || isNaN(value)) {
        throw new TypeError("Input must be a valid number.");
    }
    if (value < 0) {
        throw new RangeError("Input cannot be negative.");
    }
    return true;
}

try {
    validateInput(-5);
} catch (error) {
    console.error("Validation error:", error.name, error.message);
}

2.3. The Error Object

When an error occurs, JavaScript creates an Error object (or a subclass instance) containing useful information:

  • name: The type of the error (e.g., "TypeError", "ReferenceError", "Error").
  • message: A human-readable description of the error.
  • stack: (Non-standard but widely supported) A string representing the call stack at the time the error was thrown, invaluable for debugging.

3. Common JavaScript Error Types

Understanding built-in error types helps in writing more precise error handling logic.

3.1. Built-in Error Types

| Error Type | Description | Example |

| :-------------- | :-------------------------------------------------------------------------- | :-------------------------------------------------------------------------- |

| Error | Generic error object. Base for all other error objects. | throw new Error("Something went wrong."); |

| TypeError | An operation was performed on a value that is not of the expected type. | null.foo; (cannot read properties of null) |

| ReferenceError| An attempt was made to access a non-existent variable. | console.log(nonExistentVariable); |

| SyntaxError | Invalid JavaScript code syntax. | eval('const x =;'); (missing right-hand side) |

| RangeError | A number is outside an allowed range (e.g., array length, numeric base). | (10).toExponential(101); (precision out of range) |

| URIError | An invalid URI was passed to encodeURI() or decodeURI(). | decodeURI('%'); (incomplete URI sequence) |

| EvalError | An error occurred in conjunction with the global eval() function. | Rarely used in modern JS, often merged with TypeError or SyntaxError. |

3.2. Custom Error Types

For application-specific errors, creating custom error classes provides better semantics, easier identification, and more specific handling.

Recommendation: Extend the base Error class.

Example:


class NetworkError extends Error {
    constructor(message, statusCode) {
        super(message);
        this.name = "NetworkError"; // Custom error name
        this.statusCode = statusCode;
        // Capture stack trace for better debugging
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, NetworkError);
        }
    }
}

class ValidationError extends Error {
    constructor(message, errors = {}) {
        super(message);
        this.name = "ValidationError";
        this.errors = errors; // Specific validation details
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, ValidationError);
        }
    }
}

// Usage
function fetchData(url) {
    // Simulate network failure
    if (url.includes("fail")) {
        throw new NetworkError("Failed to fetch data from " + url, 500);
    }
    return { data: "Some data" };
}

try {
    fetchData("https://api.example.com/fail");
} catch (error) {
    if (error instanceof NetworkError) {
        console.error(`Network Error (${error.statusCode}): ${error.message}`);
        // Specific handling for network issues
    } else {
        console.error("An unexpected error occurred:", error.message);
    }
}

4. Asynchronous Error Handling

Handling errors in asynchronous operations (Promises, async/await, callbacks) requires specific approaches.

4.1. Promises (.catch())

Promises have a dedicated .catch() method for handling rejections (errors).


fetch('/api/data')
    .then(response => {
        if (!response.ok) {
            throw new NetworkError(`HTTP error! Status: ${response.status}`, response.status);
        }
        return response.json();
    })
    .then(data => console.log(data))
    .catch(error => {
        if (error instanceof NetworkError) {
            console.error("Promise Network Error:", error.message, error.statusCode);
        } else {
            console.error("Promise Error:", error.message);
        }
        // Recover or re-throw
        return Promise.reject(error); // Re-throw for subsequent catch blocks
    });

4.2. async/await (try...catch)

The async/await syntax allows you to use try...catch blocks for asynchronous code, making error handling more synchronous-looking.


async function getData() {
    try {
        const response = await fetch('/api/data');
        if (!response.ok) {
            throw new NetworkError(`HTTP error! Status: ${response.status}`, response.status);
        }
        const data = await response.json();
        console.log(data);
    } catch (error) {
        if (error instanceof NetworkError) {
            console.error("Async/Await Network Error:", error.message, error.statusCode);
        } else {
            console.error("Async/Await Error:", error.message);
        }
        // Propagate the error if necessary
        throw error;
    }
}

getData();

4.3. Callbacks (Error-First Pattern)

For older callback-based APIs, the "error-first" pattern is common, where the first argument of the callback is reserved for an error object.


function readFileAsync(filePath, callback) {
    // Simulate reading a file
    setTimeout(() => {
        if (filePath === "error.txt") {
            callback(new Error("File not found: " + filePath));
        } else {
            callback(null, "Content of " + filePath);
        }
    }, 100);
}

readFileAsync("data.txt", (err, data) => {
    if (err) {
        console.error("Callback Error:", err.message);
        return;
    }
    console.log("Callback Data:", data);
});

readFileAsync("error.txt", (err, data) => {
    if (err) {
        console.error("Callback Error:", err.message);
        return;
    }
    console.log("Callback Data:", data);
});

5. Global Error Handling

Catching errors that escape specific try...catch blocks is vital for application stability.

5.1. Browser Environment (window.onerror, window.onunhandledrejection)

  • window.onerror: Catches uncaught synchronous errors and syntax errors.
  • window.onunhandledrejection: Catches unhandled Promise rejections.

Example:


// For synchronous errors and syntax errors
window.onerror = function(message, source, lineno, colno, error) {
    console.error("Global Sync Error:", { message, source, lineno, colno, error });
    // Send error to analytics/monitoring service
    sendErrorToMonitoring({ type: "GlobalSyncError", message, source, lineno, colno, stack: error?.stack });
    return true; // Prevent default browser error message
};

// For unhandled Promise rejections
window.onunhandledrejection = function(event) {
    console.error("Global Promise Rejection:", event.reason);
    // Send error to analytics/monitoring service
    sendErrorToMonitoring({ type: "GlobalPromiseRejection", message: event.reason?.message || event.reason, stack: event.reason?.stack });
    // event.preventDefault(); // Optional: prevent default browser handling
};

function sendErrorToMonitoring(errorDetails) {
    // Placeholder for actual monitoring service integration (e.g., Sentry, Bugsnag)
    console.warn("Sending error to monitoring service:", errorDetails);
}

// Trigger a synchronous error
// nonExistentFunction();

// Trigger an unhandled promise rejection
// Promise.reject("Something went wrong in a promise!");

5.2. Node.js Environment (process.on)

  • process.on('uncaughtException'): Catches synchronous errors that were not caught by any try...catch block. Caution: This is generally considered a last resort; the process is in an undefined state after an uncaught exception, and it's safer to restart.
  • process.on('unhandledRejection'): Catches unhandled Promise rejections.

Example (Node.js):


process.on('uncaughtException', (err) => {
    console.error('Node.js Uncaught Exception:', err);
    // Log the error, perform cleanup, then exit gracefully
    sendErrorToMonitoring({ type: "NodeUncaughtException", message: err.message, stack: err.stack });
    process.exit(1); // Exit with a failure code
});

process.on('unhandledRejection', (reason, promise) => {
    console.error('Node.js Unhandled Rejection:', reason, promise);
    // Log the error, but do not exit immediately unless absolutely necessary
    sendErrorToMonitoring({ type: "NodeUnhandledRejection", message: reason?.message || reason, stack: reason?.stack });
});

// Trigger an uncaught exception (synchronous)
// setTimeout(() => {
//     throw new Error("This is an uncaught sync error!");
// }, 100);

// Trigger an unhandled promise rejection
// Promise.reject("Unhandled promise rejection!");

6. Best Practices & Recommendations

  • Catch Specific Errors: Where possible, catch specific error types (NetworkError, ValidationError) to implement targeted recovery logic. Use a generic catch (error) as a fallback.
  • Don't Swallow Errors: Avoid empty catch blocks. At a minimum, log the error. Swallowing errors makes debugging extremely difficult.
  • Log Thoroughly:

* Log the error name, message, and stack trace.

* Include context (user ID, request path, relevant input data).

* Use a centralized logging service (Sentry, LogRocket, ELK Stack, CloudWatch) for production.

  • Provide User Feedback: Inform the user when an error occurs. Avoid technical jargon. Suggest next steps (e.g., "Please try again," "Contact support").
  • Graceful Degradation: If an error occurs, try to degrade gracefully rather than crashing. For example, if a widget fails to load, display a placeholder or hide it, instead of breaking the entire page.
  • Re-throw When Necessary: If a catch block can't fully handle an error, re-throw it (throw error; or return Promise.reject(error);) so that a higher-level handler can address it.
  • Centralized Error Reporting: Implement a single function or service responsible for sending errors to logging/monitoring tools.
  • Error Boundaries (UI Frameworks): For frameworks like React, use Error Boundaries to catch errors in component trees and display fallback UIs, preventing the entire application from crashing.
  • Input Validation: Prevent errors before they happen by rigorously validating user input and API responses.
  • Idempotency: Design operations to be idempotent where possible, so retrying them after an error doesn't cause unintended side effects.

7. Handling "Test Error Types"

The request for "Test Error Types" implies a need to:

  1. Generate/Simulate errors during testing.
  2. Verify error handling logic in tests.

7.1. Strategies for Testing Error Paths

  • Unit Testing:

* Mock Dependencies: Use mocking libraries (e.g., Jest's jest.mock(), Sinon) to simulate failed network requests, database operations, or external API calls by making mocked functions throw specific errors or return rejected Promises.

* Assert Error Types/Messages: Verify that your catch blocks are correctly identifying and processing different error types and that the expected error messages or user feedback are produced.

* Example: Test that a function throws ValidationError for invalid input.

  • Integration Testing:

* Controlled Environment: Set up a test environment where you can intentionally introduce error conditions (e.g., a test server endpoint that always returns a 500 error, or a mock database that simulates connection failures).

* Error Injection: Design your application to allow "error injection" during testing, where you can programmatically trigger specific error states (e.g., a flag to force a function to throw).

  • End-to-End (E2E) Testing:

* Scenario-Based: Simulate user actions that are known to lead to error states (e.g., submitting an invalid form, trying to access a restricted resource).

* UI Verification: Assert that the user interface displays appropriate error messages, fallback components, or redirects.

7.2. Code Examples for Simulating Errors in Tests

Using Jest (Common in JavaScript testing):


// myModule.js
async function fetchDataFromAPI(url) {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`HTTP Error: ${response.status}`);
    }
    return response.json();
}

// myModule.test.js
import { fetchDataFromAPI } from './myModule';

describe('fetchDataFromAPI', () => {
    // Mock the global fetch function
    beforeAll(() => {
        global.fetch = jest.fn();
    });

    afterEach(() => {
        jest.clearAllMocks(); // Clear mocks after each test
    });

    it('should throw an error for non-ok responses', async () => {
        global.fetch.mockImplementationOnce(() =>
            Promise.resolve({
                ok: false,
                status: 404,
                json: () => Promise.resolve({ message: 'Not Found' }),
            })
        );

        await expect(fetchDataFromAPI('/api/data')).rejects.toThrow('HTTP Error: 404');
    });

    it('should handle network errors', async () => {
        global.fetch.mockImplementationOnce(() =>
            Promise.reject(new TypeError('Failed to fetch'))
        );

        await expect(fetchDataFromAPI('/api/data')).rejects.toThrow('Failed to fetch');
    });

    it('should return data for successful responses', async () => {
        const mockData = { id: 1, name: 'Test Item' };
        global.fetch.mockImplementationOnce(() =>
            Promise.resolve({
                ok: true,
                status: 200,
                json: () => Promise.resolve(mockData),
            })
        );

        await expect(fetchDataFromAPI('/api/data')).resolves.toEqual(mockData);
    });
});

8. Structured Data: Actionable Recommendations Checklist

| Recommendation | Actionable Detail | Status |

| :------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- | :----- |

| Implement try...catch...finally | Wrap synchronous code that might fail. Use finally for cleanup. | |

| Use Custom Error Classes | Extend Error for application-specific errors (e.g., NetworkError, ValidationError). | |

| Handle Async Errors | Use .catch() for Promises and try...catch for async/await. Implement error-first callbacks for older APIs. | |

| Implement Global Error Handlers | Set up window.onerror and window.onunhandledrejection (browser) or process.on handlers (Node.js). | |

| Log All Errors | Capture name, message, stack, and relevant context. Integrate with a centralized logging/monitoring service. | |

| Provide User Feedback | Display clear, non-technical error messages to users. Suggest actionable steps. | |

| Avoid Empty catch Blocks | Always log or re-throw errors, never silently swallow them. | |

| Re-throw Unhandled Errors | If a catch block cannot fully resolve an error, re-throw it for higher-level handling. | |

| Validate Input Rigorously | Prevent errors by validating all user inputs and external data proactively. | |

| Test Error Paths | Write unit, integration, and E2E tests to simulate error conditions and verify correct error handling logic. | |

| Graceful Degradation | Design components to fail gracefully, showing fallback content or partial functionality instead of crashing. | |

| Centralized Error Reporting Function | Create a dedicated utility function to handle error reporting to monitoring services, ensuring consistent data. | |

9. Conclusion

A robust error handling system is a cornerstone of professional JavaScript development. By systematically applying try...catch, leveraging custom error types, meticulously handling asynchronous operations, and implementing global catch-alls, developers can build applications that are more resilient, maintainable, and provide a superior user experience. Furthermore, integrating error handling into the testing strategy ensures that these mechanisms function as intended under various failure scenarios, leading to more stable and reliable software.

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);}});}