Error when pushing back on a list

I am a newbie to golang coming from C/C++ and I keep getting a segfault on this line of code

	name := names.Front().Next().Next()
	link := links.Front().Next().Next()
	image := images.Front()
	service := services.Front()

	var artist Artist

	// TODO: Fix nil Pointer access
	for i := 0; i < names.Len(); i++ {
		// fmt.Printf("Artist[%d]:\n\tName: %s\n\tLink: %s\n\tIcon: %s\n\tService: %s\n\t", i, name.Value, link.Value, image.Value, service.Value)

		artist = Artist{
			Name:       fmt.Sprint(name.Value),
			ArtistLink: fmt.Sprint(link.Value),
			Service:    fmt.Sprint(service.Value),
			ImageLink:  fmt.Sprint(image.Value),
		}
		artists.PushBack(artist)

		name.Next()
		link.Next()
		image.Next()
		service.Next()
	}

error:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x847948]

goroutine 1 [running]:
main.main()

what is wrong with it I have checked it with a debugger and none of the variables are nil in here is the problem the way I push back to list or is it the way I initialize the variables I just cant seem to wrap my head around it

Can you share code that we can run and reproduce the error?

Currently there is no relationshipt between the errorsnippet and the codesnippet you posted. We do not even know if this is really part of the main function or something else.

Names are used of which we do not know the value, neither do we know at which line the full error might point to…

Yea, here you go


package main

import (
	"container/list"
	"fmt"
	"github.com/gocolly/colly/v2"
	"log"
	"os"
	"strings"
	"time"
)

type Artist struct {
	Name       string
	ImageLink  string
	ArtistLink string
	Service    string
}

func (artist *Artist) SetName(name string) {
	artist.Name = name
}

func (artist *Artist) SetImage(str string) {
	artist.ImageLink = fmt.Sprintf("%s%s", "https://kemono.party", str)
}

func main() {

	// DEBUG  DEBUG  DEBUG  DEBUG  DEBUG  DEBUG //
	logfile, _ := os.Create("log.txt")
	defer func(logfile *os.File) {
		err := logfile.Close()
		if err != nil {

		}
	}(logfile)
	log.SetOutput(logfile)
	// DEBUG  DEBUG  DEBUG  DEBUG  DEBUG  DEBUG //

	url := "kemono.party"
	images := list.New()
	names := list.New()
	links := list.New()
	services := list.New()
	artists := list.New()

	COLLY := colly.NewCollector(
		colly.AllowedDomains(url, "www."+url),
	)
	COLLY.SetRequestTimeout(15 * time.Second)

	err := COLLY.Limit(&colly.LimitRule{
		DomainGlob:  url + "/*",
		Delay:       1 * time.Second,
		RandomDelay: 1 * time.Second,
	})
	HandleError(err)

	// Colly On Functions //

	COLLY.OnError(func(response *colly.Response, err error) {
		HandleError(err)
	})

	COLLY.OnRequest(func(request *colly.Request) {
		fmt.Println("Visiting", request.URL)
	})

	// Artist Icon //
	COLLY.OnHTML("img[src]", func(htmlElement *colly.HTMLElement) {
		image := htmlElement.Attr("src")
		if image != "" {
			images.PushBack("https://" + url + image)
		}
		log.Println("OnHtml Image Function", image) // DEBUG //
	})

	// Artist Name //
	COLLY.OnHTML("a[href][rel]", func(htmlElement *colly.HTMLElement) {
		name := htmlElement.Text
		if !strings.Contains(name, "\n") {
			names.PushBack(name)
		}
		log.Println("OnHtml Name Function", name) // DEBUG //
	})

	// Artist Link //
	COLLY.OnHTML("a[href][rel]", func(htmlElement *colly.HTMLElement) {
		link := htmlElement.Attr("href")
		if link != "" {
			links.PushBack(link)
		}
		log.Println("OnHtml Link Function", link) // DEBUG //

	})

	// Artist Service //
	COLLY.OnHTML(".user-card__service div", func(htmlElement *colly.HTMLElement) {
		service := htmlElement.Text
		services.PushBack(service)
	})

	COLLY.OnScraped(func(response *colly.Response) {
		log.Println("OnScrapped Function")
		fmt.Println("Finished", response.Request.URL)
	})

	// Colly Execute Function //

	err = COLLY.Visit("https://" + url + "/artists/?o=75")
	HandleError(err)

	// Print out Variables DEBUG:
	// TODO: Remove Debug and log symbols

	COLLY.Wait()

	name := names.Front().Next().Next()
	link := links.Front().Next().Next()
	image := images.Front()
	service := services.Front()

	var artist Artist

	// TODO: Fix nil Pointer access
	for i := 0; i < names.Len(); i++ {
		// fmt.Printf("Artist[%d]:\n\tName: %s\n\tLink: %s\n\tIcon: %s\n\tService: %s\n\t", i, name.Value, link.Value, image.Value, service.Value)

		artist = Artist{
			Name:       fmt.Sprint(name.Value),
			ArtistLink: fmt.Sprint(link.Value),
			Service:    fmt.Sprint(service.Value),
			ImageLink:  fmt.Sprint(image.Value),
		}
		artists.PushBack(artist)

		name.Next()
		link.Next()
		image.Next()
		service.Next()
	}

	for element := images.Front(); element != nil; element = element.Next() {
		fmt.Printf("https://%s%s\n", url, element.Value)
	}
}

func HandleError(err error) {
	if err != nil {
		log.Println("Err: ", err.Error())
	}
}


A minimal example that does not require extra dependencies to be downloaded is quite common.

In the process of preparing it, you probably had realized that the issue is related to accessing the Value of service in line 136 (as mentionened in the original error).

By further going down the route, you might have learned that service is indeed nil, as services.Front() returns nil, as services has a length of 0.

For why that might be the case, you have to check your HTML scraping yourself. I am not in the mood today to risk breaking some TOS.

1 Like