Protokoll #28008

ID28008
Zeitstempel2025-12-28 12:40:54.334557
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens2,827 (Input: 1,411, Output: 1,416)
Dauer86 ms
Request-Zeit2025-12-28 12:40:54.334557
Response-Zeit2025-12-28 12:40:54.420562

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/rules_failfast.py",
        "content": "#!\/usr\/bin\/env python3\n\"\"\"\nPost-Hook Fail Fast Regeln (WARN) - Fail Fast Principle.\n\nW8.x Regeln: Warnt bei stillen Fehlern, Error Suppression und leeren Catch-Blöcken.\n\nPrinzip: \"Ungültige Zustände werden sofort erkannt. Fehler werden früh sichtbar gemacht.\"\n\"\"\"\n\nimport re\nfrom typing import List\nfrom .rule_base import Rule, GLOBAL_ALLOWLIST\n\n\n# =============================================================================\n# W8: FAIL FAST\n# =============================================================================\n\nclass W8_1_EmptyCatch(Rule):\n    \"\"\"W8.1: Leerer catch-Block - Fehler werden verschluckt.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # Leerer catch-Block: catch(...) { } oder catch(...) { \/\/ comment }\n        # Pattern: catch mit leerem Body oder nur Whitespace\/Kommentaren\n        empty_catch_patterns = [\n            # Komplett leer\n            r\"catch\\s*\\([^)]+\\)\\s*\\{\\s*\\}\",\n            # Nur Whitespace\n            r\"catch\\s*\\([^)]+\\)\\s*\\{\\s+\\}\",\n        ]\n\n        for pattern in empty_catch_patterns:\n            matches = re.findall(pattern, content)\n            if matches:\n                warnings.append(\n                    f\"W8.1: Empty catch block detected. Errors are silently swallowed. \"\n                    f\"Log the exception or re-throw.\"\n                )\n                break\n\n        return warnings\n\n\nclass W8_2_ErrorSuppression(Rule):\n    \"\"\"W8.2: Error Suppression mit @ Operator.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # @ vor Variablen: @$var\n        var_suppression = re.findall(r\"@\\s*\\$\\w+\", content)\n\n        # @ vor Funktionen: @function()\n        func_suppression = re.findall(r\"@\\s*[a-zA-Z_]\\w*\\s*\\(\", content)\n\n        total = len(var_suppression) + len(func_suppression)\n\n        if total > 0:\n            warnings.append(\n                f\"W8.2: Error suppression with @ operator ({total}x). \"\n                f\"Handle errors explicitly instead of suppressing.\"\n            )\n\n        return warnings\n\n\nclass W8_3_CatchWithOnlyReturn(Rule):\n    \"\"\"W8.3: Catch-Block der nur return enthält - versteckt Fehlerursache.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # catch(...) { return null; } oder { return false; } oder { return; }\n        pattern = r\"catch\\s*\\([^)]+\\)\\s*\\{\\s*return\\s*(?:null|false|true|\\d+)?;\\s*\\}\"\n\n        matches = re.findall(pattern, content, re.IGNORECASE)\n        if matches:\n            warnings.append(\n                f\"W8.3: Catch block only returns without logging ({len(matches)}x). \"\n                f\"Consider logging the exception before returning.\"\n            )\n\n        return warnings\n\n\nclass W8_4_GenericException(Rule):\n    \"\"\"W8.4: Generische Exception ohne spezifischen Catch.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # catch (Exception $e) oder catch (\\Exception $e) ohne spezifischere catches davor\n        generic_catch = re.findall(r\"catch\\s*\\(\\s*\\\\?Exception\\s+\\$\\w+\\s*\\)\", content)\n\n        # Wenn generischer Catch, prüfe ob spezifische Catches vorhanden sind\n        if generic_catch:\n            specific_catch = re.findall(\n                r\"catch\\s*\\(\\s*\\\\?(?!Exception\\b)[A-Z]\\w*Exception\\s+\\$\\w+\\s*\\)\",\n                content\n            )\n\n            if not specific_catch:\n                warnings.append(\n                    f\"W8.4: Only generic Exception catch without specific handlers. \"\n                    f\"Consider catching specific exceptions first.\"\n                )\n\n        return warnings\n\n\nclass W8_5_ThrowInDestructor(Rule):\n    \"\"\"W8.5: Exception in Destructor - kann zu unerwartetem Verhalten führen.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # Finde __destruct Methoden\n        destruct_match = re.search(\n            r\"function\\s+__destruct\\s*\\([^)]*\\)\\s*(?::\\s*\\w+)?\\s*\\{\",\n            content\n        )\n\n        if destruct_match:\n            # Suche throw innerhalb des Destructors (vereinfacht)\n            destruct_start = destruct_match.end()\n            # Finde das Ende des Destructors\n            brace_count = 1\n            pos = destruct_start\n            while pos < len(content) and brace_count > 0:\n                if content[pos] == '{':\n                    brace_count += 1\n                elif content[pos] == '}':\n                    brace_count -= 1\n                pos += 1\n\n            destruct_body = content[destruct_start:pos]\n\n            if re.search(r\"\\bthrow\\s+\", destruct_body):\n                warnings.append(\n                    \"W8.5: Exception thrown in __destruct(). \"\n                    \"This can cause unexpected behavior. Catch and log instead.\"\n                )\n\n        return warnings\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n    W8_1_EmptyCatch(),\n    W8_2_ErrorSuppression(),\n    W8_3_CatchWithOnlyReturn(),\n    W8_4_GenericException(),\n    W8_5_ThrowInDestructor(),\n]\n"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/tools\/ki-protokoll\/claude-hook\/quality\/rules_failfast.py",
        "content": "#!\/usr\/bin\/env python3\n\"\"\"\nPost-Hook Fail Fast Regeln (WARN) - Fail Fast Principle.\n\nW8.x Regeln: Warnt bei stillen Fehlern, Error Suppression und leeren Catch-Blöcken.\n\nPrinzip: \"Ungültige Zustände werden sofort erkannt. Fehler werden früh sichtbar gemacht.\"\n\"\"\"\n\nimport re\nfrom typing import List\nfrom .rule_base import Rule, GLOBAL_ALLOWLIST\n\n\n# =============================================================================\n# W8: FAIL FAST\n# =============================================================================\n\nclass W8_1_EmptyCatch(Rule):\n    \"\"\"W8.1: Leerer catch-Block - Fehler werden verschluckt.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # Leerer catch-Block: catch(...) { } oder catch(...) { \/\/ comment }\n        # Pattern: catch mit leerem Body oder nur Whitespace\/Kommentaren\n        empty_catch_patterns = [\n            # Komplett leer\n            r\"catch\\s*\\([^)]+\\)\\s*\\{\\s*\\}\",\n            # Nur Whitespace\n            r\"catch\\s*\\([^)]+\\)\\s*\\{\\s+\\}\",\n        ]\n\n        for pattern in empty_catch_patterns:\n            matches = re.findall(pattern, content)\n            if matches:\n                warnings.append(\n                    f\"W8.1: Empty catch block detected. Errors are silently swallowed. \"\n                    f\"Log the exception or re-throw.\"\n                )\n                break\n\n        return warnings\n\n\nclass W8_2_ErrorSuppression(Rule):\n    \"\"\"W8.2: Error Suppression mit @ Operator.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # @ vor Variablen: @$var\n        var_suppression = re.findall(r\"@\\s*\\$\\w+\", content)\n\n        # @ vor Funktionen: @function()\n        func_suppression = re.findall(r\"@\\s*[a-zA-Z_]\\w*\\s*\\(\", content)\n\n        total = len(var_suppression) + len(func_suppression)\n\n        if total > 0:\n            warnings.append(\n                f\"W8.2: Error suppression with @ operator ({total}x). \"\n                f\"Handle errors explicitly instead of suppressing.\"\n            )\n\n        return warnings\n\n\nclass W8_3_CatchWithOnlyReturn(Rule):\n    \"\"\"W8.3: Catch-Block der nur return enthält - versteckt Fehlerursache.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # catch(...) { return null; } oder { return false; } oder { return; }\n        pattern = r\"catch\\s*\\([^)]+\\)\\s*\\{\\s*return\\s*(?:null|false|true|\\d+)?;\\s*\\}\"\n\n        matches = re.findall(pattern, content, re.IGNORECASE)\n        if matches:\n            warnings.append(\n                f\"W8.3: Catch block only returns without logging ({len(matches)}x). \"\n                f\"Consider logging the exception before returning.\"\n            )\n\n        return warnings\n\n\nclass W8_4_GenericException(Rule):\n    \"\"\"W8.4: Generische Exception ohne spezifischen Catch.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # catch (Exception $e) oder catch (\\Exception $e) ohne spezifischere catches davor\n        generic_catch = re.findall(r\"catch\\s*\\(\\s*\\\\?Exception\\s+\\$\\w+\\s*\\)\", content)\n\n        # Wenn generischer Catch, prüfe ob spezifische Catches vorhanden sind\n        if generic_catch:\n            specific_catch = re.findall(\n                r\"catch\\s*\\(\\s*\\\\?(?!Exception\\b)[A-Z]\\w*Exception\\s+\\$\\w+\\s*\\)\",\n                content\n            )\n\n            if not specific_catch:\n                warnings.append(\n                    f\"W8.4: Only generic Exception catch without specific handlers. \"\n                    f\"Consider catching specific exceptions first.\"\n                )\n\n        return warnings\n\n\nclass W8_5_ThrowInDestructor(Rule):\n    \"\"\"W8.5: Exception in Destructor - kann zu unerwartetem Verhalten führen.\"\"\"\n\n    def check(self, file_path: str, content: str) -> List[str]:\n        warnings = []\n\n        # Finde __destruct Methoden\n        destruct_match = re.search(\n            r\"function\\s+__destruct\\s*\\([^)]*\\)\\s*(?::\\s*\\w+)?\\s*\\{\",\n            content\n        )\n\n        if destruct_match:\n            # Suche throw innerhalb des Destructors (vereinfacht)\n            destruct_start = destruct_match.end()\n            # Finde das Ende des Destructors\n            brace_count = 1\n            pos = destruct_start\n            while pos < len(content) and brace_count > 0:\n                if content[pos] == '{':\n                    brace_count += 1\n                elif content[pos] == '}':\n                    brace_count -= 1\n                pos += 1\n\n            destruct_body = content[destruct_start:pos]\n\n            if re.search(r\"\\bthrow\\s+\", destruct_body):\n                warnings.append(\n                    \"W8.5: Exception thrown in __destruct(). \"\n                    \"This can cause unexpected behavior. Catch and log instead.\"\n                )\n\n        return warnings\n\n\n# =============================================================================\n# RULE COLLECTION\n# =============================================================================\n\nRULES = [\n    W8_1_EmptyCatch(),\n    W8_2_ErrorSuppression(),\n    W8_3_CatchWithOnlyReturn(),\n    W8_4_GenericException(),\n    W8_5_ThrowInDestructor(),\n]\n",
        "structuredPatch": [],
        "originalFile": null
    }
}
← Vorheriger Zur Liste Nächster →