O dia em que a LLM derrubou o isaCloud

Reading Time: 2 minutes

Era uma vez… não, foi hoje mesmo.

No final de semana passado comecei a implementação do gerenciador de failover do isaCloud – o isaCloud HA Manager. Foi uma codificação intensa e consegui liberar no mesmo final de semana a versão de testes da aplicação.

Ela é um daemon feito em Go onde criei algumas rotinas para assegurar a role de cada servidor do cluster, revisando o estado de serviços, replicação e endereçamento do serviço.

Eu costumo codificar com um auxílio básico de LLM para codificação. Utilizo o Windsurf (antigo Codeium) que oferece um serviço razoável para me economizar digitação de algumas linhas de códigos e lógicas repetidas ao longo do projeto.

Mas eu fui pega pela comodidade e aceitei uma sugestão do assistente para fazer a transposição de um objeto io.ReadCloser (o body da resposta de uma API) para uma estrutura personalizada IPInfoT usando json.NewDecoder().

client := &http.Client{}
resp, err := client.Do(&req)
if err != nil {
  log.Error.Println("error getting public IP:", err)
  return err
}
defer resp.Body.Close()
var ipInfo IPInfoT
err = json.NewDecoder(resp.Body).Decode(&ipInfo)
if err != nil {
  log.Error.Println("error decoding ipinfo.io response:", err)
  return err
}

Porém eu sempre realizei essas operações usando json.Unmarshal().

client := &http.Client{}
resp, err := client.Do(&req)
if err != nil {
  log.Error.Println("error getting public IP:", err)
  return err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
  log.Error.Println("error getting public IP - body reading:", err)
  return err
}
var ipInfo IPInfoT
err = json.Unmarshal(body, &ipInfo)
if err != nil {
  log.Error.Println("error decoding ipinfo.io response:", err)
  return err
}

Ao aceitar a sugestão da LLM usando a função destacada no primeiro código, quando a aplicação recebeu uma resposta do serviço ipinfo.io que não batia com o contrato da estrutura IPInfoT, a função não disparou um erro, fazendo com que o tratamento na linha subsequente, que verifica se err != nil não fosse validado e a rotina seguiu adiante, com uma informação inválida na variável ipInfo que ao ser comparada com o ip atual do serviço (que responde no hostname im.isacloud.cc), identificou que o servidor estaria no modo standby, porém ele é primário.

Ao identificá-lo (incorretamente) como standby, a aplicação estava mandando o container que roda o serviço do isaCloud parar – e por isso toda vez que eu iniciava o container, segundos depois ele era derrubado “gracefully” e não reiniciava sozinho.

A moral da história é…. releia o código e identifique se algum padrão teu foi modificado por sugestão de LLM… e revise! No meu caso, nem o teste para o tratamento de erro pegou esse caso excepcional.

E foi assim que a LLM derrubou o serviço isaCloud.

Com ranço (pela LLM) e carinho por vocês,

Isadora