- ❌ Hardcoded Language: Only C++ was supported (language_id='52')
- ❌ Incomplete Status Handling: Only handled Accepted (3) and Wrong Answer (4)
- ❌ No Error Handling: API failures caused crashes without user feedback
- ❌ Invalid Field Name: Used 'inputs' instead of 'stdin' for Judge0 API
- ❌ No Language Tracking: Database didn't record which language was used
Before:
case['language_id'] = '52' # C++ TODO: make dynamicAfter:
# 11 languages supported with dropdown selector
language_id = form.language.data # Dynamic from user selection
case['language_id'] = language_idLanguages Added:
- Python (71)
- Java (62)
- C++ (54)
- C (50)
- JavaScript (63)
- Kotlin (78)
- Go (60)
- Ruby (72)
- Rust (73)
- SQL (82)
- TypeScript (74)
Before:
if submission_data['status']['id'] == 3:
results.append('Accepted')
if submission_data['status']['id'] == 4:
results.append('Wrong Answer')After:
# Comprehensive status handling (14 status codes)
if status_id == 3:
results.append('Accepted')
elif status_id == 4:
results.append('Wrong Answer')
elif status_id == 5:
results.append('Time Limit Exceeded')
elif status_id == 6:
results.append('Compilation Error')
elif status_id in [7, 8, 9, 10, 11, 12]:
results.append('Runtime Error')
elif status_id == 13:
results.append('Internal Error')
elif status_id == 14:
results.append('Exec Format Error')Status Indicators:
| Status | Before | After |
|---|---|---|
| Accepted | ✅ | ✅ |
| Wrong Answer | ❌ | ❌ |
| Compilation Error | 💥 | 💥 |
| Time Limit Exceeded | ⚙️ | ⏱️ |
| Runtime Error | ⚙️ | 💣 |
| Internal/Format Error | ⚙️ | ❗ |
| Processing | ⚙️ | ⚙️ |
Before:
# No error handling - crashes on API failure
conn.request("POST", "/submissions/batch?base64_encoded=true", payload, headers)
res = conn.getresponse()
data = res.read()
tokens = []
for d in json.loads(data.decode("utf-8")):
if 'token' in d:
tokens.append(d['token'])
else:
tokens.append(None)After:
try:
conn.request("POST", "/submissions/batch?base64_encoded=true", payload, headers)
res = conn.getresponse()
data = res.read()
response_text = data.decode("utf-8")
# Validate JSON parsing
try:
response_data = json.loads(response_text)
except json.JSONDecodeError as e:
flash('Error communicating with Judge0 API. Please try again.', 'danger')
return redirect(url_for('show_prob', prob_id=prob_id))
# Validate response structure
if not isinstance(response_data, list):
flash('Unexpected response from Judge0 API. Please try again.', 'danger')
return redirect(url_for('show_prob', prob_id=prob_id))
# Check for valid tokens
if all(token is None for token in tokens):
flash('Failed to submit code to Judge0. Please check your code and try again.', 'danger')
return redirect(url_for('show_prob', prob_id=prob_id))
except http.client.HTTPException as e:
flash('Connection error with Judge0 API. Please try again.', 'danger')
return redirect(url_for('show_prob', prob_id=prob_id))
except Exception as e:
flash('An unexpected error occurred. Please try again.', 'danger')
return redirect(url_for('show_prob', prob_id=prob_id))Before:
- No language selection
- Code editor always in C++ mode
After:
- Language dropdown selector
- Dynamic editor syntax highlighting
- Synced with selected language
JavaScript Enhancement:
// Change editor mode when language is selected
languageSelect.addEventListener('change', function() {
var selectedLanguage = this.value;
var mode = languageModes[selectedLanguage] || 'c_cpp';
editor.session.setMode("ace/mode/" + mode);
});Before:
class Submission(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, ...)
problem_id = db.Column(db.Integer, ...)
# No language trackingAfter:
class Submission(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, ...)
problem_id = db.Column(db.Integer, ...)
language_id = db.Column(db.String(10), nullable=False, default='54') # Track languageBefore:
case['inputs'] = f.read() # Wrong field nameAfter:
case['stdin'] = f.read() # Correct Judge0 API fieldAll validation tests passed ✅:
- ✓ Language field exists in Code form
- ✓ Found 11 language choices
- ✓ Expected languages found in choices
- ✓ All important status codes (3-14) are mapped
- ✓ All form languages have editor mode mappings
- ✓ Submission model has language_id column
- ✅ Can now submit solutions in 11 different languages
- ✅ Clear error messages when API fails
- ✅ Better status indicators for different failure types
- ✅ Syntax highlighting matches selected language
- ✅ Proper exception handling prevents crashes
- ✅ Validates API responses before processing
- ✅ Complies with Judge0 API specification
- ✅ Tracks submission metadata for analytics
- ✅ Status codes mapped in constant dictionary
- ✅ Language modes centralized
- ✅ Migration script for database updates
- ✅ Comprehensive documentation
- bemo/forms.py (+14 lines)
- bemo/routes.py (+150 lines, refactored submission handling)
- bemo/models.py (+1 field)
- bemo/templates/problem.html (+40 lines for language selector and JS)
- migrate_add_language.py (new, 28 lines)
- JUDGE0_IMPROVEMENTS.md (new, documentation)
- .gitignore (+2 lines)
For existing installations:
# 1. Pull changes
git pull
# 2. Run migration
python migrate_add_language.py
# 3. Restart application
python run.pyPotential improvements for later:
- Move API key to environment variables
- Add per-language time limits
- Support custom test case generation
- Add code snippet templates for each language
- Implement language-specific linting
- Add submission history filtering by language