I'm creating a GOLang Linux distribution installer. The architecture is straight forward. I have N parameters and uses them in N installation steps. Summarizing:
- Every step implements a interface with the Run method.
- For each step S, do S.Run(parameters), if failed, handle the error.
The complete source code is here: https://github.com/Munix-Developers/munix-standalone-installer/blob/master/installer/partitions-step.go
I've created a Partition Step. Used to create the desired partitions on the disk. The main loop for the step is as follows:
func (p PartitionsStep) Run(c parser.InstallConfig) error {
log.Println("starting partition step")
var err error = nil
for _, d := range c.Storage.Devices {
log.Printf("creating gpt label for %s", d.Device)
err = createGptLabel(d)
if err != nil {
return err
}
for _, p := range d.Partitions {
err = createPartition(d, p)
if err != nil {
return err
}
}
err = discoverPartitionDevices(&d)
if err != nil {
return err
}
}
return nil
}
Looking at this code, I've noticed that there is too many "if err != nil; return error". In the inner functions there are more if statements like that, for example in the discoverPartitionsDevice
function:
// Since parted doesn't returns which is the device that was created, we need to find it manually. This function searches
// for partitions where the label starts with "mx" and exists in the configuration
func discoverPartitionDevices(d *parser.DeviceConfig) error {
blkidOut, err := runBlkid()
if err != nil {
return err
}
sort.SliceStable(d.Partitions, func(i, j int) bool {
return d.Partitions[i].Mount <= d.Partitions[j].Mount
})
for _, line := range strings.Split(blkidOut, "\n") {
line = strings.ReplaceAll(line, ": PARTLABEL=", " ")
line = strings.ReplaceAll(line, "\"", "")
data := strings.Split(line, " ")
err = proccessBlkidLine(d, data)
if err != nil {
return err
}
}
return nil
}
So, is there a better way to handle this type of error in GOLang?