Продвинутая обработка ошибок
Управление ошибками с учетом контекста
Комплексный шаблон обработки ошибок
package main
import (
"context"
"fmt"
"log"
"os/exec"
"time"
)
func executeCommandWithTimeout(command string, timeout time.Duration) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
cmd := exec.CommandContext(ctx, "bash", "-c", command)
output, err := cmd.CombinedOutput()
if err!= nil {
if ctx.Err() == context.DeadlineExceeded {
return fmt.Errorf("command timed out: %v", err)
}
if exitError, ok := err.(*exec.ExitError); ok {
return fmt.Errorf("command failed with exit code %d: %s",
exitError.ExitCode(), string(output))
}
return err
}
return nil
}
func main() {
err := executeCommandWithTimeout("sleep 10", 5*time.Second)
if err!= nil {
log.Println("Execution error:", err)
}
}
Стратегия классификации ошибок
graph TD
A[Command Execution] --> B{Error Type}
B --> |Timeout| C[Context Timeout]
B --> |Exit Code| D[Non-Zero Exit]
B --> |System Error| E[Execution Failure]
Техники обработки ошибок
Техника |
Описание |
Сценарий использования |
Тайм-аут контекста |
Ограничение времени выполнения команды |
Долго выполняющиеся команды |
Подробный разбор ошибок |
Извлечение конкретной информации об ошибке |
Сложные рабочие процессы скриптов |
Механизмы повторения |
Реализация автоматических повторов |
Периодические сбои |
Продвинутое логирование и отчетность об ошибках
package main
import (
"fmt"
"log"
"os/exec"
"syscall"
)
type CommandResult struct {
Success bool
ExitCode int
Output string
ErrorDetail string
}
func executeAndAnalyzeCommand(command string) CommandResult {
cmd := exec.Command("bash", "-c", command)
output, err := cmd.CombinedOutput()
result := CommandResult{
Output: string(output),
}
if err!= nil {
result.Success = false
if exitError, ok := err.(*exec.ExitError); ok {
status := exitError.Sys().(syscall.WaitStatus)
result.ExitCode = status.ExitStatus()
result.ErrorDetail = fmt.Sprintf("Command failed with exit code %d", result.ExitCode)
} else {
result.ErrorDetail = err.Error()
}
} else {
result.Success = true
}
return result
}
func main() {
result := executeAndAnalyzeCommand("ls /nonexistent")
if!result.Success {
log.Printf("Command Execution Failed: %s", result.ErrorDetail)
log.Printf("Exit Code: %d", result.ExitCode)
log.Printf("Output: %s", result.Output)
}
}
Лучшие практики обработки ошибок
- Используйте контекст для управления тайм-аутами
- Реализуйте комплексный разбор ошибок
- Логируйте подробную информацию об ошибках
- Создавайте пользовательские типы ошибок при необходимости
В LabEx мы подчеркиваем важность создания надежных механизмов обработки ошибок, которые обеспечивают ясное понимание причин неудачного выполнения команд.