☕ ☕ TuskLang Java Error Handling Guide
☕ TuskLang Java Error Handling Guide
"We don't bow to any king" - Java Edition
Master TuskLang error handling in Java with comprehensive coverage of error types, Java integration patterns, exception handling, and best practices for robust configuration management.
🎯 Error Handling Basics
Common Error Types
Syntax errors
app_name: "My App" # Missing closing quote
version: 1.0.0 # Missing quotes for string
port: "8080" # String instead of numberReference errors
database_host: $undefined_variable
api_url: $base_url + "/" + $missing_varValidation errors
email: "invalid-email"
port: 70000 # Out of range
password: "123" # Too short
Java Error Handling
import org.tusklang.java.TuskLang;
import org.tusklang.java.config.TuskConfig;
import org.tusklang.java.errors.TuskLangException;
import org.tusklang.java.errors.ParseException;
import org.tusklang.java.errors.ValidationException;
import java.util.Map;@TuskConfig
public class ErrorHandlingConfig {
public String appName;
public String version;
public int port;
public String email;
public String password;
}
public class ErrorHandlingExample {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
try {
// Parse configuration with error handling
ErrorHandlingConfig config = parser.parseFile("config.tsk", ErrorHandlingConfig.class);
System.out.println("Configuration loaded successfully");
System.out.println("App: " + config.appName + " v" + config.version);
} catch (ParseException e) {
System.err.println("Parse error: " + e.getMessage());
System.err.println("Line: " + e.getLineNumber());
System.err.println("Column: " + e.getColumnNumber());
System.err.println("Context: " + e.getContext());
} catch (ValidationException e) {
System.err.println("Validation error: " + e.getMessage());
System.err.println("Field: " + e.getField());
System.err.println("Value: " + e.getValue());
System.err.println("Rule: " + e.getRule());
} catch (TuskLangException e) {
System.err.println("TuskLang error: " + e.getMessage());
System.err.println("Error type: " + e.getErrorType());
System.err.println("File: " + e.getFileName());
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
e.printStackTrace();
}
}
}
🔧 Error Types and Handling
Parse Errors
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ParseException;
import java.util.Map;public class ParseErrorHandling {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
try {
// Parse with potential syntax errors
Map<String, Object> config = parser.parseFile("config.tsk");
} catch (ParseException e) {
System.err.println("=== Parse Error ===");
System.err.println("Message: " + e.getMessage());
System.err.println("Line: " + e.getLineNumber());
System.err.println("Column: " + e.getColumnNumber());
System.err.println("Context: " + e.getContext());
System.err.println("File: " + e.getFileName());
// Get error details
String errorLine = e.getErrorLine();
String suggestion = e.getSuggestion();
if (errorLine != null) {
System.err.println("Error line: " + errorLine);
}
if (suggestion != null) {
System.err.println("Suggestion: " + suggestion);
}
// Handle specific parse error types
switch (e.getParseErrorType()) {
case SYNTAX_ERROR:
System.err.println("Syntax error detected");
break;
case MISSING_QUOTE:
System.err.println("Missing quote detected");
break;
case INVALID_SECTION:
System.err.println("Invalid section syntax");
break;
case UNEXPECTED_TOKEN:
System.err.println("Unexpected token");
break;
}
}
}
}
Validation Errors
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ValidationException;
import org.tusklang.java.validation.ValidationResult;
import java.util.List;public class ValidationErrorHandling {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
try {
// Parse with validation
ValidationResult result = parser.parseWithValidation("config.tsk", ErrorHandlingConfig.class);
if (!result.isValid()) {
System.err.println("=== Validation Errors ===");
List<ValidationException> errors = result.getValidationExceptions();
for (ValidationException error : errors) {
System.err.println("Field: " + error.getField());
System.err.println("Message: " + error.getMessage());
System.err.println("Value: " + error.getValue());
System.err.println("Rule: " + error.getRule());
System.err.println("---");
}
// Get error summary
Map<String, Integer> errorSummary = result.getErrorSummary();
System.err.println("Error summary: " + errorSummary);
// Get errors by field
List<ValidationException> portErrors = result.getValidationExceptionsForField("port");
List<ValidationException> emailErrors = result.getValidationExceptionsForField("email");
if (!portErrors.isEmpty()) {
System.err.println("Port errors: " + portErrors.size());
}
if (!emailErrors.isEmpty()) {
System.err.println("Email errors: " + emailErrors.size());
}
}
} catch (ValidationException e) {
System.err.println("=== Single Validation Error ===");
System.err.println("Field: " + e.getField());
System.err.println("Message: " + e.getMessage());
System.err.println("Value: " + e.getValue());
System.err.println("Rule: " + e.getRule());
System.err.println("Severity: " + e.getSeverity());
}
}
}
Reference Errors
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ReferenceException;
import java.util.Map;public class ReferenceErrorHandling {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
try {
// Parse with potential reference errors
Map<String, Object> config = parser.parseFile("config.tsk");
} catch (ReferenceException e) {
System.err.println("=== Reference Error ===");
System.err.println("Message: " + e.getMessage());
System.err.println("Variable: " + e.getVariableName());
System.err.println("Context: " + e.getContext());
System.err.println("Line: " + e.getLineNumber());
// Handle specific reference error types
switch (e.getReferenceErrorType()) {
case UNDEFINED_VARIABLE:
System.err.println("Undefined variable: " + e.getVariableName());
System.err.println("Available variables: " + e.getAvailableVariables());
break;
case CIRCULAR_REFERENCE:
System.err.println("Circular reference detected");
System.err.println("Reference chain: " + e.getReferenceChain());
break;
case INVALID_REFERENCE:
System.err.println("Invalid reference syntax");
break;
}
}
}
}
🔄 Exception Handling Patterns
Try-Catch with Recovery
import org.tusklang.java.TuskLang;
import org.tusklang.java.config.TuskConfig;
import org.tusklang.java.errors.TuskLangException;
import java.util.Map;@TuskConfig
public class RecoveryConfig {
public String appName;
public String version;
public int port;
public DatabaseConfig database;
}
public class ErrorRecoveryExample {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
RecoveryConfig config = null;
// Try to load primary configuration
try {
config = parser.parseFile("config.tsk", RecoveryConfig.class);
System.out.println("Primary configuration loaded successfully");
} catch (TuskLangException e) {
System.err.println("Primary configuration failed: " + e.getMessage());
// Try to load fallback configuration
try {
config = parser.parseFile("config.fallback.tsk", RecoveryConfig.class);
System.out.println("Fallback configuration loaded successfully");
} catch (TuskLangException fallbackError) {
System.err.println("Fallback configuration also failed: " + fallbackError.getMessage());
// Use default configuration
config = createDefaultConfig();
System.out.println("Using default configuration");
}
}
// Use the configuration (either primary, fallback, or default)
if (config != null) {
System.out.println("App: " + config.appName + " v" + config.version);
System.out.println("Port: " + config.port);
}
}
private static RecoveryConfig createDefaultConfig() {
RecoveryConfig config = new RecoveryConfig();
config.appName = "Default App";
config.version = "1.0.0";
config.port = 8080;
return config;
}
}
Error Collection and Reporting
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ErrorCollector;
import org.tusklang.java.errors.TuskLangException;
import java.util.List;public class ErrorCollectionExample {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
ErrorCollector errorCollector = new ErrorCollector();
// Set up error collector
parser.setErrorCollector(errorCollector);
try {
// Parse configuration (errors will be collected)
Map<String, Object> config = parser.parseFile("config.tsk");
} catch (TuskLangException e) {
// Handle any uncaught errors
errorCollector.addError(e);
}
// Report all collected errors
List<TuskLangException> errors = errorCollector.getErrors();
if (!errors.isEmpty()) {
System.err.println("=== Error Report ===");
System.err.println("Total errors: " + errors.size());
for (TuskLangException error : errors) {
System.err.println("Error: " + error.getMessage());
System.err.println("Type: " + error.getClass().getSimpleName());
System.err.println("File: " + error.getFileName());
System.err.println("Line: " + error.getLineNumber());
System.err.println("---");
}
// Generate error summary
Map<String, Integer> errorSummary = errorCollector.getErrorSummary();
System.err.println("Error summary: " + errorSummary);
// Check if configuration is usable despite errors
if (errorCollector.hasCriticalErrors()) {
System.err.println("Critical errors detected - configuration may not be usable");
} else {
System.out.println("Configuration loaded with warnings");
}
} else {
System.out.println("Configuration loaded successfully - no errors");
}
}
}
Graceful Degradation
import org.tusklang.java.TuskLang;
import org.tusklang.java.config.TuskConfig;
import org.tusklang.java.errors.TuskLangException;
import java.util.Map;
import java.util.Optional;@TuskConfig
public class GracefulConfig {
public String appName;
public String version;
public Optional<Integer> port;
public Optional<DatabaseConfig> database;
}
public class GracefulDegradationExample {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
try {
GracefulConfig config = parser.parseFile("config.tsk", GracefulConfig.class);
// Use configuration with graceful degradation
System.out.println("App: " + config.appName);
System.out.println("Version: " + config.version);
// Handle optional fields gracefully
int port = config.port.orElse(8080);
System.out.println("Port: " + port);
if (config.database.isPresent()) {
DatabaseConfig db = config.database.get();
System.out.println("Database: " + db.host + ":" + db.port);
} else {
System.out.println("Database configuration not available - using defaults");
// Use default database configuration
}
} catch (TuskLangException e) {
System.err.println("Configuration error: " + e.getMessage());
System.err.println("Using minimal configuration");
// Create minimal working configuration
GracefulConfig minimalConfig = createMinimalConfig();
System.out.println("Minimal app: " + minimalConfig.appName);
}
}
private static GracefulConfig createMinimalConfig() {
GracefulConfig config = new GracefulConfig();
config.appName = "Minimal App";
config.version = "1.0.0";
config.port = Optional.empty();
config.database = Optional.empty();
return config;
}
}
🔧 Error Utilities
Error Analysis
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ErrorAnalyzer;
import org.tusklang.java.errors.TuskLangException;
import java.util.List;
import java.util.Map;public class ErrorAnalysisExample {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
ErrorAnalyzer analyzer = new ErrorAnalyzer();
try {
parser.parseFile("config.tsk");
} catch (TuskLangException e) {
// Analyze the error
Map<String, Object> analysis = analyzer.analyzeError(e);
System.out.println("=== Error Analysis ===");
System.out.println("Error type: " + analysis.get("errorType"));
System.out.println("Severity: " + analysis.get("severity"));
System.out.println("Recoverable: " + analysis.get("recoverable"));
System.out.println("Common cause: " + analysis.get("commonCause"));
System.out.println("Suggested fix: " + analysis.get("suggestedFix"));
// Get similar errors
List<TuskLangException> similarErrors = analyzer.findSimilarErrors(e);
if (!similarErrors.isEmpty()) {
System.out.println("Similar errors found: " + similarErrors.size());
}
// Get error patterns
Map<String, Integer> errorPatterns = analyzer.getErrorPatterns();
System.out.println("Error patterns: " + errorPatterns);
}
}
}
Error Recovery
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ErrorRecovery;
import org.tusklang.java.errors.TuskLangException;
import java.util.Map;public class ErrorRecoveryExample {
public static void main(String[] args) {
TuskLang parser = new TuskLang();
ErrorRecovery recovery = new ErrorRecovery();
try {
parser.parseFile("config.tsk");
} catch (TuskLangException e) {
// Attempt automatic recovery
String recoveredContent = recovery.attemptRecovery(e);
if (recoveredContent != null) {
System.out.println("=== Automatic Recovery ===");
System.out.println("Recovery successful");
System.out.println("Recovered content:");
System.out.println(recoveredContent);
// Try to parse recovered content
try {
Map<String, Object> config = parser.parse(recoveredContent);
System.out.println("Recovered configuration parsed successfully");
} catch (TuskLangException recoveryError) {
System.err.println("Recovery failed: " + recoveryError.getMessage());
}
} else {
System.err.println("Automatic recovery not possible");
System.err.println("Manual intervention required");
// Provide manual recovery suggestions
List<String> suggestions = recovery.getRecoverySuggestions(e);
System.out.println("Recovery suggestions:");
for (String suggestion : suggestions) {
System.out.println(" - " + suggestion);
}
}
}
}
}
🧪 Testing Error Handling
Unit Tests
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import static org.junit.jupiter.api.Assertions.*;
import org.tusklang.java.TuskLang;
import org.tusklang.java.errors.ParseException;
import org.tusklang.java.errors.ValidationException;
import org.tusklang.java.errors.ReferenceException;class ErrorHandlingTest {
private TuskLang parser;
@BeforeEach
void setUp() {
parser = new TuskLang();
}
@Test
void testParseErrorHandling() {
String invalidContent = """
app_name: "My App" # Missing closing quote
version: 1.0.0 # Missing quotes
port: "8080" # String instead of number
""";
ParseException exception = assertThrows(ParseException.class, () -> {
parser.parse(invalidContent);
});
assertEquals("Missing closing quote", exception.getMessage());
assertTrue(exception.getLineNumber() > 0);
assertTrue(exception.getColumnNumber() > 0);
}
@Test
void testValidationErrorHandling() {
String invalidContent = """
app_name: "Test App"
version: "1.0.0"
port: 70000 # Invalid port
email: "invalid-email" # Invalid email
""";
ValidationException exception = assertThrows(ValidationException.class, () -> {
parser.parseWithValidation(invalidContent, ErrorHandlingConfig.class);
});
assertTrue(exception.getMessage().contains("Port must be between 1 and 65535"));
assertEquals("port", exception.getField());
assertEquals(70000, exception.getValue());
}
@Test
void testReferenceErrorHandling() {
String invalidContent = """
app_name: "Test App"
version: "1.0.0"
port: $undefined_variable
""";
ReferenceException exception = assertThrows(ReferenceException.class, () -> {
parser.parse(invalidContent);
});
assertEquals("undefined_variable", exception.getVariableName());
assertTrue(exception.getMessage().contains("Undefined variable"));
}
@Test
void testErrorRecovery() {
String invalidContent = """
app_name: "Test App" # Missing closing quote
version: "1.0.0"
port: 8080
""";
try {
parser.parse(invalidContent);
fail("Should have thrown ParseException");
} catch (ParseException e) {
// Test error recovery
ErrorRecovery recovery = new ErrorRecovery();
String recoveredContent = recovery.attemptRecovery(e);
assertNotNull(recoveredContent);
assertTrue(recoveredContent.contains("Test App"));
assertTrue(recoveredContent.contains("1.0.0"));
assertTrue(recoveredContent.contains("8080"));
// Verify recovered content can be parsed
Map<String, Object> config = parser.parse(recoveredContent);
assertEquals("Test App", config.get("app_name"));
assertEquals("1.0.0", config.get("version"));
assertEquals(8080, config.get("port"));
}
}
}
🔧 Troubleshooting
Common Error Handling Issues
1. Errors Not Caught
// Ensure proper exception hierarchy
try {
config = parser.parseFile("config.tsk", Config.class);
} catch (TuskLangException e) {
// Catches all TuskLang-specific exceptions
System.err.println("TuskLang error: " + e.getMessage());
} catch (Exception e) {
// Catches any other exceptions
System.err.println("Unexpected error: " + e.getMessage());
}
2. Error Recovery Not Working
// Ensure error recovery is properly configured
ErrorRecovery recovery = new ErrorRecovery();
recovery.setEnableAutoFix(true);
recovery.setMaxRecoveryAttempts(3);String recoveredContent = recovery.attemptRecovery(exception);
3. Error Analysis Issues
// Ensure error analyzer has proper context
ErrorAnalyzer analyzer = new ErrorAnalyzer();
analyzer.setIncludeContext(true);
analyzer.setIncludeSuggestions(true);Map<String, Object> analysis = analyzer.analyzeError(exception);
📚 Best Practices
Error Handling Strategy
1. Fail fast for critical errors
// Critical configuration errors should fail immediately
try {
config = parser.parseFile("config.tsk", Config.class);
} catch (ParseException e) {
// Critical error - fail immediately
throw new ConfigurationException("Critical configuration error", e);
}
2. Graceful degradation for non-critical errors
// Non-critical errors should allow graceful degradation
try {
config = parser.parseFile("config.tsk", Config.class);
} catch (ValidationException e) {
// Non-critical error - use defaults
config = createDefaultConfig();
logger.warn("Using default configuration due to validation error: " + e.getMessage());
}
3. Comprehensive error reporting
// Provide detailed error information
ErrorCollector collector = new ErrorCollector();
parser.setErrorCollector(collector);try {
config = parser.parseFile("config.tsk", Config.class);
} catch (TuskLangException e) {
collector.addError(e);
}
// Report all errors
if (!collector.getErrors().isEmpty()) {
generateErrorReport(collector.getErrors());
}
Error Recovery Patterns
1. Multiple fallback strategies
// Try multiple configuration sources
Config config = null;// Try primary configuration
try {
config = parser.parseFile("config.tsk", Config.class);
} catch (TuskLangException e) {
// Try environment-specific configuration
try {
String env = System.getProperty("APP_ENV", "development");
config = parser.parseFile("config." + env + ".tsk", Config.class);
} catch (TuskLangException e2) {
// Use default configuration
config = createDefaultConfig();
}
}
2. Partial configuration loading
// Load configuration partially
Map<String, Object> partialConfig = new HashMap<>();try {
Map<String, Object> fullConfig = parser.parseFile("config.tsk");
// Extract valid parts
if (fullConfig.containsKey("app_name")) {
partialConfig.put("app_name", fullConfig.get("app_name"));
}
if (fullConfig.containsKey("version")) {
partialConfig.put("version", fullConfig.get("version"));
}
} catch (TuskLangException e) {
// Use partial configuration
System.err.println("Partial configuration loaded: " + partialConfig);
}
📚 Next Steps
1. Master error types - Understand all TuskLang error types and their causes 2. Implement error recovery - Create robust error recovery mechanisms 3. Use error analysis - Leverage error analysis for debugging and improvement 4. Add comprehensive testing - Create thorough error handling test suites 5. Optimize error reporting - Implement effective error reporting and logging
---
"We don't bow to any king" - You now have complete mastery of TuskLang error handling in Java! From basic error catching to sophisticated recovery mechanisms, you can build robust, fault-tolerant configuration systems that gracefully handle any error condition.