Img project fail to deploy on Cloudflare

Yesterday, I shared my portfolio with the Kaiyuanshe group. While discussing my img site, I encountered the first issue – images are supposed to zoom in when clicked, but they actually open in a new tab.

I checked the Git commits and reverted them one by one until I successfully resolved the issue. The problem stemmed from my attempt to implement view transitions using "@view-transition", inspired by an Astro blog post titled "Zero-JavaScript View Transitions", which is not supported in my current browser.

Just when I believed I had resolved all issues, I stumbled upon another problem – all the alt texts I had assigned to images had vanished. Subsequently, upon examining the Cloudflare Pages deployment logs, I discovered the errors being displayed:

23:58:47.472	 generating static routes 
23:58:47.492	15:58:47 ▶ src/pages/internet.astro
23:58:48.324	15:58:47   └─ /internet/index.htmlSyntaxError: Unexpected token 'o', "[object Obj"... is not valid JSON
23:58:48.324	    at JSON.parse (<anonymous>)
23:58:48.324	    at altTexts (file:///opt/buildhome/repo/dist/chunks/_layout_Dry1hoQ2.mjs:1045:19)
23:58:48.324	    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
23:58:48.325	    at async file:///opt/buildhome/repo/dist/chunks/_layout_Dry1hoQ2.mjs:1050:23
23:58:48.364	 (+872ms)
23:58:48.366	15:58:48 ▶ src/pages/index.astro
23:58:48.548	15:58:48   └─ /index.htmlSyntaxError: Unexpected token 'o', "[object Obj"... is not valid JSON
23:58:48.549	    at JSON.parse (<anonymous>)
23:58:48.549	    at altTexts (file:///opt/buildhome/repo/dist/chunks/_layout_Dry1hoQ2.mjs:1045:19)
23:58:48.549	    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
23:58:48.549	    at async file:///opt/buildhome/repo/dist/chunks/_layout_Dry1hoQ2.mjs:1050:23
23:58:48.628	 (+262ms)
23:58:48.628	15:58:48 ✓ Completed in 1.16s.

At first, I was perplexed and unable to comprehend why this error had arisen. Nevertheless, I managed to identity the problematic code, which resembled the following:

import Cloudflare from 'cloudflare';
import dotenv from 'dotenv';
dotenv.config();

const client = new Cloudflare({
  apiToken: process.env.CF_KV_API_TOKEN,
});

const kvOptions = {
  account_id: 'xxx',
};
const altTexts = async () => {
  try {
    const data = await client.kv.namespaces.values.get(
      'xxx',
      'img-altTexts',
      kvOptions,
    );
    return JSON.parse(data);
  } catch (error) {
    console.error(error);
    return [];
  }
};

const altTextData = await altTexts();

I didn't know how to debug this. With the help of , added console.log(data), it get normal result locally but unexpected Response() object on Cloudflare:

Uncertain about how to debug this problem, I sought help from @luojiyin1987. Together, we inserted console.log(data), which successfully produced the desired outcome during local testing. However, upon deployment on Cloudflare, an unexpected Response() object was returned:

23:00:19.726	15:00:19 ▶ src/pages/index.astro
23:00:20.016	15:00:19   └─ /index.htmlResponse {
23:00:20.016	  size: 0,
23:00:20.017	  timeout: 0,
23:00:20.017	  [Symbol(Body internals)]: {
23:00:20.017	    body: PassThrough {
23:00:20.017	      _events: [Object],
23:00:20.017	      _readableState: [ReadableState],
23:00:20.017	      _writableState: [WritableState],
23:00:20.017	      allowHalfOpen: true,
23:00:20.017	      _maxListeners: undefined,
23:00:20.018	      _eventsCount: 5,
23:00:20.018	      [Symbol(shapeMode)]: true,
23:00:20.018	      [Symbol(kCapture)]: false,
23:00:20.018	      [Symbol(kCallback)]: null
23:00:20.018	    },
23:00:20.018	    disturbed: false,
23:00:20.018	    error: null
23:00:20.018	  },
23:00:20.018	  [Symbol(Response internals)]: {
23:00:20.019	    url: 'https://api.cloudflare.com/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/values/img-altTexts',
23:00:20.019	    status: 200,
23:00:20.019	    statusText: 'OK',
23:00:20.019	    headers: Headers { [Symbol(map)]: [Object: null prototype] },
23:00:20.019	    counter: 0
23:00:20.019	  }
23:00:20.019	}
23:00:20.019	SyntaxError: Unexpected token 'o', "[object Response]" is not valid JSON
23:00:20.020	    at JSON.parse (<anonymous>)
23:00:20.020	    at altTexts (file:///opt/buildhome/repo/dist/chunks/_layout_FKCzc6Aa.mjs:1050:19)
23:00:20.020	    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
23:00:20.020	    at async file:///opt/buildhome/repo/dist/chunks/_layout_FKCzc6Aa.mjs:1056:23
23:00:20.078	 (+352ms)

I researched JSON.parse(), which converts a string containing text (string, boolean, JSON, array) into corresponding data types (string, boolean, JSON, array). It doesn't support trailing commas or single quotes. In contrast, JSON.stringify() is used to convert objects or other data types into strings.

Following this, @luojiyin1987 suggested that utilizing the Cloudflare REST API might be a better approach. Consequently, I commenced updating the code, and the final version is provided below:

import fetch from 'node-fetch';
import dotenv from 'dotenv';

dotenv.config();

interface AltTextItem {
	name: string;
	altText: string;
}

const url =
	'https://api.cloudflare.com/client/v4/accounts/account_id/storage/kv/namespaces/namespace_id/values/img-altTexts';

const options = {
	method: 'GET',
	headers: {
		'Content-Type': 'application/json',
		Authorization: `Bearer ${process.env.CF_KV_API_TOKEN}`,
	},
};

const altTexts = async (): Promise<AltTextItem[]> => {
	try {
		const response = await fetch(url, options);
		if (!response.ok) throw new Error('Network response was not ok');
		const data = (await response.json()) as AltTextItem[];
		return data;
	} catch (error) {
		console.error(
			'There was a problem with the fetch problem operation:',
			error,
		);
		return [];
	}
};

const altTextData = await altTexts();

To get this code spend me hours time. After this process of problem solving, I have some thoughts:

  • Pure is better. REST API better than SDK. Don't have much time to dig the Cloduflare SDK, just use REST API.
  • When solving the problem, @luojiyin1987 made me realized that my JS foundation is weak, need more work on it. I feel a little shame about it.
  • When I couldn't seek the right solution, I feel panic and inconfident about myself, and hate the problem which made me so uncomfortable. Then I persuade myself, made me blieve that If I want to make progress, this kind of situation will be more common. When I adopted in this, I will chanllenge more difficult problems to make progress.

Investing substantial time in refining the code underscored valuable insights:

  • Simple is better. Using REST API is preferable to SDK. Due to time constraints, opted for REST API over Cloudflare SDK.
  • Collaboration with @luojiyin1987 revealed gaps in my JavaScript skills, prompting a realization of the need for improvement. Experience prompted a sense of embarrassment.
  • Initial struggle with finding the right solution led to feelings of panic and self-doubt. Despite discomfort, realized such situations are necessary for growth. Embracing challenges will enable progerss.

Question

How to find where the bug is?

more info

欢迎通过「邮件」或者点击「这里」告诉我你的想法
Welcome to tell me your thoughts via "email" or click "here"