Custom provider error handling

Hi,

Im not sure if this has been addressed in some previous topic so apologies if this is the case.

Im writing a custom provider and i’m having a hard time getting the plugin to output errors.

I have my CRUD functions and for example the Create function looks like this:

func resourceServerCreate(d *schema.ResourceData, m interface{}) error {
	apiClient := m.(Client)
	name := d.Get("name").(string)
	log.Printf("CALLING CREATE")
	id, err := createInstance(name, apiClient.apiKey, apiClient.apiSecret, apiClient.environment)

	if err != nil {
		return fmt.Errorf("ERROR ERROR ERROR ERROR: %s", err)
	}

	d.SetId(id)
	return resourceServerRead(d, m)
}

This function is calling another function to make the actual API call, i never get to see the actual error printed to stdout but instead i always get the same error:

Error: Provider produced inconsistent result after apply

When applying changes to xsp_server.my-server, provider
registry.terraform.io/-/xsp” produced an unexpected new value for was
present, but now absent.

This is a bug in the provider, which should be reported in the provider’s own
issue tracker.

If have tried declaring the TF_LOG=1 environment variable for verbose output but the error is not visible even then.

Can anyone give me pointers on how to be able to have terraform output the actual error?

Also if more information about my code is needed im happy to be more explicit.

Thanks

Hi @ErkkaKorpi! Sorry, I’m not 100% clear on what you mean. Are you saying the ERROR ERROR ERROR ERROR part isn’t getting output? Are you sure err is not nil? That smells like a bug to me if you can show err is non-nil and the error still isn’t returning. At that point, I’d request an issue with as much info as you can provide–Terraform version, SDK version, if you have a minimal reproduction that’s super helpful, etc.

Or are you saying CALLING CREATE is what you’re looking for and not seeing? It’s unintuitive, but you have to prefix logs with the level they’re logged at. So [TRACE] CALLING CREATE, for example, or [DEBUG] CALLING CREATE. From what I understand, due to the multitude of logging subsystems in Terraform, using [TRACE] is the most reliable way to make sure logs show up. That requires setting TF_LOG=TRACE.

Continuing the discussion from Custom provider error handling:

Hi Paddy, thanks for replying,

Yeah what i was trying to say that the "ERROR ERROR..." part is not coming through when the apply fails. While debugging this i have set the api client im calling to do the request to send it to a URL that i know will reject it.

This is how the createInstance function looks like:

func createInstance(name string, key string, secret string, env string) (string, error) {
	var url string

	if env == "localhost" {
		url = "http://" + env + ":8888/api/createInstance"
	} else {
		url = "url That will fail"
	}

	requestBody, err := json.Marshal(map[string]string{
		"Name": name,
	})

	if err != nil {
		return "", err
	}

	cryptic := generateHmac(secret, requestBody)
	client := &http.Client{}
	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
	req.Header.Set("apikey", key)
	req.Header.Set("signature", cryptic)
	req.Header.Set("Content-Type", "application/json")
	log.Printf("SENDING REQUEST TO " + url)
	resp, err := client.Do(req)

	if err != nil {
		log.Printf("ERROR ERROR ERROR ERROR")
		return "", err
	}

	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		return "", err
	}

	create := &CreateResponse{}
	_ = json.Unmarshal([]byte(body), &create)
	return create.ID, nil
}

Actually when i run terraform with TF_LOG=TRACE i can see all other log messages i have set but when terraform errors i cant see any of the error logging lines i have set up in cases when err != nil

Im going to try to see if my createInstance actually does return error when the request fails to be sure

Actually it does look like the error is nil and im actually getting a response. My apologies, im fairly new at GO and was apparently being too confident that the request would resolve in error rather than getting a response, i will need to work on this more

Thank you so much for pointing this out, i had a feeling that it could be more likely to be a configuration error rather than a problem with terraform