'Go: Invalid memory address or nil pointer dereference when reading files and strings at same time

I have the following function waitForInput that listens for TCP input, after the connection has been created and that one has been assigned to the client struct which is one of the input params of that one.

func waitForInput(client *util.Client) {
    defer close(out)

    var dstFile = ""
    var fileBytes = make([]byte, 0)
    reader := bufio.NewReader(client.Connection)
    for {

        if client.SendingOperation == "command" {
            line, err := reader.ReadBytes('\n')
            myString := strings.TrimSpace(string(line))
            action, _, body := getAction(myString)

            if action == "send" {
                dstFile = body
                client.SetSendingOperation("file")
            }
            //Do some other stuff

        } else {
            fmt.Printf("IN FILE %s %s \n", client.Username, client.SendingOperation)
            bytes, err := reader.ReadBytes('\n')
            if err == nil {
                fmt.Printf("ERROR:: ", err.Error())
            }

            fmt.Printf("The bytes: %s \n", bytes)
            fmt.Printf("fileBytes: %s \n", fileBytes)

            if err != nil {
                if err == io.EOF {
                    writeBytesToFile(dstFile, fileBytes)
                    //Go back to listen commands first
                    client.SetSendingOperation("command")
                    fileBytes = make([]byte, 0)
                }
            }else {
                fileBytes = append(fileBytes, bytes...)
            }
        }
    }
}

That function can read either commands or files, which are sent as byte arrays appended (if it's command + file) like messageBytes = append(commandBytes, fileBytes...). It works fine when sending only commands and not both, commands + files. But when sending commands and files I got the following error: panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x2 addr=0x18 pc=0x1007285b0], The weird thing is that if I comment that if check: if err == nil {fmt.Printf("ERROR:: ", err.Error())}, the code prints the bytes resulting from fmt.Printf("The bytes: %s \n", bytes), so I don't know whats going on, and I've been trying to fix it by days, so does anyone know what to do there, or does anyone know an alternative for reading commands as strings and files passed in a connection from a client to a server at the same time?



Solution 1:[1]

if err == nil {
    fmt.Printf("ERROR:: ", err.Error())
}

This will definitely give panic: runtime error: invalid memory address or nil pointer dereference since you are accessing err.Error() after you have already checked err == nil. So in this case nil.Error() is throwing the error.

I would suggest removing the above code code block and modify the error handling further down the code.

fmt.Printf("IN FILE %s %s \n", client.Username, client.SendingOperation)
bytes, err := reader.ReadBytes('\n')

// REMOVE THIS
// if err == nil {
//     fmt.Printf("ERROR:: ", err.Error())
// }

fmt.Printf("The bytes: %s \n", bytes)
fmt.Printf("fileBytes: %s \n", fileBytes)

if err != nil {
    if err == io.EOF {
        writeBytesToFile(dstFile, fileBytes)
        //Go back to listen commands first
        client.SetSendingOperation("command")
        fileBytes = make([]byte, 0)
    } else { // ADD THIS ELSE BLOCK
        fmt.Printf("ERROR:: ", err.Error())
    }
} else {
    fileBytes = append(fileBytes, bytes...)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Suyash Medhavi