Técnicas para Lidar com erros em Vlang Utilizando os.system e Operador or


No meu projeto (hobby) de automatizar as configurações e restore numa nova instalação de S.O (Fedora ou Debian like), resolvi (por tempo livre) transformá-lo de Shell Script para Vlang.
E nisto encontrei alguns desafios.
Um exemplo sobre tratar erro/gerar logs:
A function install_fonts
em Vlang:
fn install_fonts() {
local_fonts_dir := os.home_dir() + '/.local/share/fonts'
if !os.exists(local_fonts_dir) {
os.mkdir_all(local_fonts_dir) or {
println('Failed to create ~/.local/share/fonts directory')
return }
}
}
Ele move o diretório para /.local/share/fonts
na home ~
do usuário, e logo abaixo uso o bloco if para validar se o path não existe e cria-lo.
Nesta validação, ele retorna um valor do tipo Result
E com o operador or { ... }
tento tratar algum erro colocando um println
na tela caso falhe na criação do path e um return no final.
Porém o or
só funciona com resultados do tipo (type) Result ou Option.
Result: um valor que pode estar presente ou um erro. Pode ser representado por !
Option: um valor que pode ou não estar presente. Pode ser representado por ?
Exemplo de Option type:
fn func() ?int {
return none
}
Exemplo de Result type:
fn func() !int {
return error('Some error')
}
Ao manipular esses tipos, você pode usar o bloco or
para manipular a ausência de um valor ou um erro. Por exemplo:
a := func() or { "default" }
A variável a
será "default" se func() retornar none ou error
Novamente, o operador or
só pode ser usado com funções que retornam Option
ou Result
.
Mas lá naquele script em Shell/Bash, a maioria das execuções é de comandos no sistema, logo, precisarei usar a função os.system()
para executá-los.
E eis o problema: o os.system vai retornar um valor inteiro devido a execução com sucesso do comando no linux.
Qualquer execução de comando no Linux retorna um número inteiro, que pode ser verificado com $?
. O valor 0
indica sucesso, enquanto valores diferentes de 0
indicam falhas, com diferentes códigos de erro dependendo do comando. Além do output no terminal de quem está executando.
Para conseguir tratar erros neste caso (exibir uma mensagem caso falhe a execução do comando do linux via Vlang), uma alternativa a seguir é:
exit_code := os.system('wget -c ${fonts_pack} -P ${local_fonts_dir}')
if exit_code != 0 {
println('Failed to download fonts.zip')
return
}
Movo a execução do os.system()
para a variável exit_code
, e depois, num bloco if, com isto, pode-se validar se retorna ou não com sucesso (type result
) usando o or
.
E com isto, temos o tratamento de erro e a exibição de mensagens em caso de erro em todas as etapas da execução:
fn install_fonts() {
local_fonts_dir := os.home_dir() + '/.local/share/fonts'
if !os.exists(local_fonts_dir) {
os.mkdir_all(local_fonts_dir) or {
println('Failed to create ~/.local/share/fonts directory')
return
}
}
hack_fonts := 'https://github.com/ryanoasis/nerd-fonts/releases/download/v2.2.2/Hack.zip'
installhack := os.system('wget -c ${hack_fonts} -P ${local_fonts_dir}')
if installhack != 0 {
println('Failed to download Hack.zip')
return
}
println('Hack.zip downloaded and saved to ${local_fonts_dir}') }
É isso…
Caso queira ver todo o código, siga em
Subscribe to my newsletter
Read articles from Esli Silva directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Esli Silva
Esli Silva
Linux hard user since 2003, IT manager, DevOps, Sysadmin, SRE, teacher, Bass player, Krav Maga fighter and Marksman (Sport Shooter).