Class: ActivePostgres::ErrorHandler
- Inherits:
-
Object
- Object
- ActivePostgres::ErrorHandler
- Defined in:
- lib/active_postgres/error_handler.rb
Constant Summary collapse
- ERROR_GUIDES =
Define common errors and their troubleshooting steps
{ ssh_connection: { title: 'SSH Connection Failed', hints: [ 'Ensure SSH keys are properly configured for the target host', 'Verify the host is reachable: ping <hostname>', 'Check SSH config in ~/.ssh/config', 'Try manual SSH connection: ssh <user>@<host>' ] }, private_network_connectivity: { title: 'Private Network Connectivity Failed', hints: [ 'Ensure the private/VPC network (or WireGuard) is configured on all nodes', 'Verify interfaces are up and have the expected IPs', 'Check firewall/security-group rules for the replication subnet', 'Test connectivity: ping <private_ip>', 'Confirm routing tables/NAT rules allow node-to-node traffic' ] }, postgresql_not_starting: { title: 'PostgreSQL Failed to Start', hints: [ 'Check PostgreSQL logs: sudo tail -100 /var/log/postgresql/postgresql-*-main.log', 'Verify configuration: sudo -u postgres pg_lsclusters', 'Check if port 5432 is already in use: sudo lsof -i :5432', 'Verify data directory permissions: ls -la /var/lib/postgresql/*/main', 'Check systemd status: sudo systemctl status postgresql' ] }, repmgr_clone_failed: { title: 'Repmgr Standby Clone Failed', hints: [ 'Verify primary PostgreSQL is running and accessible', 'Check pg_hba.conf allows replication from standby IP', 'Test connection: psql -h <primary_ip> -U repmgr -d repmgr', 'Ensure sufficient disk space on standby', 'Check repmgr logs for detailed error messages', 'Verify repmgr user has replication privileges' ] }, repmgr_register_failed: { title: 'Repmgr Registration Failed', hints: [ 'Ensure primary is registered first: repmgr cluster show', 'Verify standby can connect to primary PostgreSQL', 'Check repmgr.conf conninfo is correct', 'Ensure repmgr database and tables exist on primary', 'Verify standby PostgreSQL is running before registration' ] }, ssl_certificate_error: { title: 'SSL Certificate Error', hints: [ 'Check certificate file permissions (should be 600 for .key)', 'Verify certificate paths in postgresql.conf', 'Ensure certificate is valid: openssl x509 -in <cert> -text -noout', 'Check certificate ownership: ls -la /etc/postgresql/*/main/server.*' ] }, disk_space_error: { title: 'Insufficient Disk Space', hints: [ 'Check available disk space: df -h /var/lib/postgresql', 'Clean up old PostgreSQL logs if needed', 'Consider increasing volume size', 'Check for large files: du -sh /var/lib/postgresql/* | sort -h' ] }, authentication_failed: { title: 'PostgreSQL Authentication Failed', hints: [ 'Verify pg_hba.conf has correct authentication methods', "Check if user exists: sudo -u postgres psql -c '\\du'", 'Ensure password is set correctly', 'Reload PostgreSQL after pg_hba.conf changes: sudo systemctl reload postgresql', 'Check PostgreSQL logs for authentication errors' ] } }.freeze
Class Method Summary collapse
-
.handle(error, context: {}, error_type: nil) ⇒ Object
Handle an error with context and helpful hints.
-
.identify_error_type(message) ⇒ Object
Identify error type from error message.
-
.show_generic_troubleshooting ⇒ Object
Show generic troubleshooting steps.
-
.show_troubleshooting_guide(error_type) ⇒ Object
Show troubleshooting guide for a specific error type.
-
.with_handling(context: {}) ⇒ Object
Wrap a block with error handling.
Class Method Details
.handle(error, context: {}, error_type: nil) ⇒ Object
Handle an error with context and helpful hints
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/active_postgres/error_handler.rb', line 94 def handle(error, context: {}, error_type: nil) puts "\n#{'=' * 80}" puts '❌ ERROR OCCURRED'.center(80) puts '=' * 80 puts "\nError: #{LogSanitizer.sanitize(error.)}" puts "Type: #{error.class.name}" if context.any? puts "\nContext:" context.each do |key, value| puts " #{key}: #{LogSanitizer.sanitize(value.to_s)}" end end if error.backtrace&.any? puts "\nBacktrace (last 5 lines):" error.backtrace.first(5).each do |line| puts " #{LogSanitizer.sanitize(line)}" end end # Try to identify error type from message if not provided error_type ||= identify_error_type(error.) if error_type && ERROR_GUIDES[error_type] show_troubleshooting_guide(error_type) else show_generic_troubleshooting end puts "\n#{'=' * 80}\n" end |
.identify_error_type(message) ⇒ Object
Identify error type from error message
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/active_postgres/error_handler.rb', line 129 def identify_error_type() case .downcase when /ssh|connection refused|network unreachable/ :ssh_connection when /private network|vpn|wireguard network/ :private_network_connectivity when /postgresql.*not.*start|cluster.*not.*running/ :postgresql_not_starting when /repmgr.*clone|data directory/ :repmgr_clone_failed when /repmgr.*register|unable to connect to.*primary/ :repmgr_register_failed when /ssl|certificate|tls/ :ssl_certificate_error when /no space|disk full/ :disk_space_error when /authentication|password|pg_hba/ :authentication_failed end end |
.show_generic_troubleshooting ⇒ Object
Show generic troubleshooting steps
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/active_postgres/error_handler.rb', line 165 def show_generic_troubleshooting puts "\n#{'-' * 80}" puts '🔧 TROUBLESHOOTING STEPS' puts '-' * 80 puts "\n1. Check the error message and backtrace above" puts '2. Verify all hosts are accessible via SSH' puts '3. Check PostgreSQL logs on affected hosts' puts '4. Run with --verbose for more detailed output' puts '5. Consult the documentation: https://github.com/your-repo/active_postgres' end |
.show_troubleshooting_guide(error_type) ⇒ Object
Show troubleshooting guide for a specific error type
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/active_postgres/error_handler.rb', line 151 def show_troubleshooting_guide(error_type) guide = ERROR_GUIDES[error_type] return unless guide puts "\n#{'-' * 80}" puts "🔧 TROUBLESHOOTING: #{guide[:title]}" puts '-' * 80 puts "\nTry these steps:" guide[:hints].each_with_index do |hint, index| puts " #{index + 1}. #{hint}" end end |
.with_handling(context: {}) ⇒ Object
Wrap a block with error handling
177 178 179 180 181 182 |
# File 'lib/active_postgres/error_handler.rb', line 177 def with_handling(context: {}) yield rescue StandardError => e handle(e, context: context) raise end |