CodeMentor-PRO / error_detector.py
Urvxshhhhh0201's picture
Update error_detector.py
253bd94 verified
Raw
History Blame Contribute Delete
5.28 kB
"""
CodeMentor Pro - Multi-type Error Detection
Now routes Python, JavaScript, C++, and Java through REAL execution:
- Python -> local subprocess sandbox (default; set
config.PYTHON_EXECUTION_ENGINE=judge0 to route it through Judge0 too)
- JavaScript/C++/Java -> Judge0 (real compile/interpret + execute)
Whenever a real engine can't be used for a given submission (Judge0 down,
rate-limited, or no engine mapped for the language) we transparently fall
back to the same LLM static-estimate prompt used before, so the app never
just fails a submission outright - it degrades honestly instead.
"""
from sandbox import execute_code
from store import record_submission, get_weakness_note
from llm import call_groq_json
from prompts import LOGICAL_ERROR_PROMPT, STATIC_ANALYSIS_PROMPT
def _run_static_estimate(code: str, language: str) -> dict:
"""LLM-based fallback when no real execution happened for this submission."""
out = {
"syntax": {"found": False, "message": ""},
"runtime": {"found": False, "message": ""},
"tle": {"found": False, "message": "", "runtime_seconds": None},
"syntax_err": False,
"tle_err": False,
}
try:
static_result = call_groq_json(STATIC_ANALYSIS_PROMPT, f"Language: {language}\n\nCode:\n{code}")
except Exception as e:
out["syntax"]["message"] = f"{language} static analysis unavailable: {e}"
return out
if static_result.get("syntax_error_found"):
out["syntax"] = {
"found": True,
"message": static_result.get(
"syntax_error_message", "Potential syntax issue detected (unverified β€” static estimate)."
),
}
out["syntax_err"] = True
else:
out["syntax"]["message"] = (
f"No obvious syntax issues found for {language} "
"(unverified β€” static LLM estimate, not real execution)."
)
if static_result.get("runtime_error_found"):
out["runtime"] = {"found": True, "message": static_result.get("runtime_error_message", "")}
if static_result.get("tle_risk_found"):
out["tle"] = {
"found": True,
"message": static_result.get(
"tle_risk_message", "Potential performance risk (unverified β€” static estimate)."
),
"runtime_seconds": None,
}
out["tle_err"] = True
return out
def detect_errors(code: str, language: str) -> dict:
result = {
"syntax": {"found": False, "message": ""},
"runtime": {"found": False, "message": ""},
"tle": {"found": False, "message": "", "runtime_seconds": None},
"logical": {"found": False, "issues": []},
"weakness_note": "",
"verified_by_execution": False,
}
syntax_err = False
tle_err = False
exec_result = execute_code(code, language)
if not exec_result.engine_failure:
# Real execution happened - Python (local) or C++/Java (Judge0).
result["verified_by_execution"] = True
result["tle"]["runtime_seconds"] = exec_result.runtime_seconds
if exec_result.error_type == "syntax":
result["syntax"] = {"found": True, "message": exec_result.error_message}
syntax_err = True
elif exec_result.error_type == "runtime":
result["runtime"] = {"found": True, "message": exec_result.error_message}
elif exec_result.error_type == "tle":
result["tle"] = {
"found": True,
"message": exec_result.error_message,
"runtime_seconds": exec_result.runtime_seconds,
}
tle_err = True
else:
# No engine available for this submission (unmapped language, or a
# live Judge0 failure) - fall back to the LLM static estimate.
static = _run_static_estimate(code, language)
result["syntax"] = static["syntax"]
result["runtime"] = static["runtime"]
result["tle"] = static["tle"]
syntax_err = static["syntax_err"]
tle_err = static["tle_err"]
if language in ("python", "javascript", "cpp", "java"):
# This language normally HAS a real engine, so engine_failure here
# means Judge0 failed just for this run - worth surfacing clearly
# rather than silently looking identical to "no engine exists".
result["syntax"]["message"] = (
f"⚠️ Real execution unavailable this run ({exec_result.error_message}) β€” "
f"showing an unverified static estimate instead. {result['syntax']['message']}"
)
logical_err = False
if not syntax_err:
try:
llm_result = call_groq_json(LOGICAL_ERROR_PROMPT, f"Language: {language}\n\nCode:\n{code}")
if llm_result.get("logical_errors_found"):
logical_err = True
result["logical"] = {"found": True, "issues": llm_result.get("issues", [])}
except Exception as e:
result["logical"] = {"found": False, "issues": [], "error": str(e)}
record_submission(language, code, syntax_error=syntax_err, logical_error=logical_err, tle=tle_err)
result["weakness_note"] = get_weakness_note(language)
return result