2
\$\begingroup\$

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?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.