Home  >  Article  >  Backend Development  >  Can't get Golang library to return anything other than nil to controller

Can't get Golang library to return anything other than nil to controller

王林
王林forward
2024-02-11 15:45:09697browse

无法让 Golang 库向控制器返回除 nil 之外的任何内容

php editor Baicao introduces to you the problem: the Golang library cannot return anything except nil to the controller. In Golang development, the controller is a key component in handling requests, but sometimes you may encounter the problem of being unable to return content other than nil. This may cause some features to not work properly. Fortunately, there are some solutions we can take to solve this problem and ensure that the library returns what it needs. In this article, we'll explore a few common solutions to help you resolve this issue.

Question content

This is a golang kid, so I guess I'm missing something obvious. After a few days of trying, I decided to get some help. :-)

The code I posted is working except in the case where the user requests the creation of a new client certificate/keybag (this is the openvpn server management webui) and a client with the same name already exists. Even in this case, the new client package is not created, but an erroneous alert message is displayed indicating that a new client package has been created.

I know I need to redesign the controller to show a different alert banner depending on whether the name exists or not. However, I've been stuck on retrieving anything other than "nil" from the library.

The golang controller code is as follows:

func (c *certificatescontroller) post() {
    c.tplname = "certificates.html"
    flash := beego.newflash()

    cparams := newcertparams{}
    if err := c.parseform(&cparams); err != nil {
        beego.error(err)
        flash.error(err.error())
        flash.store(&c.controller)
    } else {
        if vmap := validatecertparams(cparams); vmap != nil {
            c.data["validation"] = vmap
        } else {
            if err := lib.createcertificate(cparams.name, cparams.passphrase); err != nil {
                beego.error(err)
                flash.error(err.error())
                flash.store(&c.controller)
            } else {
                fmt.println(err)
                flash.success("certificate for the name \"" + cparams.name + "\" created")
                flash.store(&c.controller)
            }
        }
    }
    c.showcerts()
}

And library functions called through lib.createcertificate:

func CreateCertificate(name string, passphrase string) error {
    rsaPath := models.GlobalCfg.OVConfigPath + "easy-rsa"
    rsaIndex := models.GlobalCfg.OVConfigPath + "easy-rsa/pki/index.txt"
    pass := false
    if passphrase != "" {
        pass = true
    }
    certs, err := ReadCerts(rsaIndex)
    if err != nil {
        //      beego.Debug(string(output))
        beego.Error(err)
        //      return err
    }
    Dump(certs)
    exists := false
    for _, v := range certs {
        if v.Details.Name == name {
            exists = true
        }
    }
    if !exists && !pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --batch build-client-full %s nopass",
                rsaPath, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    if !exists && pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --passout=pass:%s build-client-full %s",
                rsaPath, passphrase, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    if exists {
        return err
    }
    return err
}

I've changed every return in the library to err and inserted fmt.println(err) in the second "else" statement of the controller, but all I get is nil.

SOLUTION

So, I was able to figure out how to deal with this issue. A little more Googling and I found a post that was at least adjacent to what I was trying to achieve. In the end, I only had to add/change 3 lines in my certificate store. I need to import the "errors" library, add a custom error in the form newerror :=errors.new("error! there is already a valid or invalidcertificate for that name") and change only the last one returned return newerror . I did learn a thing or two about how go handles errors!

The following is the update code for the certificate store:

func CreateCertificate(name string, passphrase string) error {
    rsaPath := models.GlobalCfg.OVConfigPath + "easy-rsa"
    rsaIndex := models.GlobalCfg.OVConfigPath + "easy-rsa/pki/index.txt"
    pass := false
    newError := errors.New("Error! There is already a valid or invalid certificate for that name")
    if passphrase != "" {
        pass = true
    }
    certs, err := ReadCerts(rsaIndex)
    if err != nil {
        //      beego.Debug(string(output))
        beego.Error(err)
        //      return err
    }
    Dump(certs)
    exists := false
    for _, v := range certs {
        if v.Details.Name == name {
            exists = true
        }
    }
    if !exists && !pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --batch build-client-full %s nopass",
                rsaPath, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    if !exists && pass {
        cmd := exec.Command("/bin/bash", "-c",
            fmt.Sprintf(
                "%s/easyrsa --passout=pass:%s build-client-full %s",
                rsaPath, passphrase, name))
        cmd.Dir = models.GlobalCfg.OVConfigPath
        output, err := cmd.CombinedOutput()
        if err != nil {
            beego.Debug(string(output))
            beego.Error(err)
            return err
        }
        return nil
    }
    return newError
}

Now if I try to add an openvpn client whose name already exists:

The above is the detailed content of Can't get Golang library to return anything other than nil to controller. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete