ซีรีส์ เขียนโปรแกรมพื้นฐาน · ตอนที่ 2 จาก 7
อ่าน error ให้เป็น: ดู 3 อย่างก่อนส่งให้ AI แก้
16 ต.ค. 2569 · อ่าน 14 นาที
จอแดงเต็มหน้าไม่ได้แปลว่าโปรแกรมพังทั้งหมด error ส่วนใหญ่บอกไว้แล้วว่าเป็นปัญหาชนิดไหนและเกิดที่บรรทัดไหน สิ่งที่ยังขาดคือข้อมูลว่าคุณเพิ่งทำอะไรไป ตอนที่ 2 ของซีรีส์เขียนโปรแกรมพื้นฐานพาอ่าน error จริง 3 ตัวจาก Node.js และ Python ทีละส่วน พร้อมวิธีส่ง error ให้ AI แบบที่ได้คำตอบตรงจุด

บทความนี้เป็นตอนที่ 2 ของซีรีส์ "เขียนโปรแกรมพื้นฐาน" สำหรับคนที่ให้ AI เขียนโค้ดให้ แต่ไม่ได้เป็นโปรแกรมเมอร์
เมื่อกดรันโปรแกรมที่ AI เขียนให้ แล้วจอเต็มไปด้วยภาษาอังกฤษสิบกว่าบรรทัด หลายคนคัดลอกไปวางแล้วพิมพ์ว่า "แก้ให้หน่อย" บางครั้งก็ได้ผล แต่บางครั้ง AI แก้จนข้อความแจ้งข้อผิดพลาด (error) หายไป ทั้งที่ปัญหาจริงยังอยู่
error ไม่ได้แปลว่าโปรแกรมพังทั้งหมด แต่เป็นรายงานว่าเกิดอะไรขึ้น ถ้ารู้ว่าต้องดูตรงไหน คุณจะอ่านออกได้ในเวลาไม่ถึงนาที และส่งให้ AI แบบที่ได้คำตอบตรงจุดกว่าเดิม
ข้อมูล ณ ตุลาคม 2569 error ทุกตัวในบทความนี้เรารันจริงบนเครื่อง ด้วย Node.js 23.11 และ Python 3.13 ถ้าคุณใช้รุ่นอื่น ให้ดูที่ชนิดและตำแหน่งของ error เป็นหลัก
error คือรายงานว่าเกิดอะไรขึ้น ไม่ใช่คำตำหนิ
MDN (เว็บคู่มือสำหรับนักพัฒนาเว็บที่ Mozilla ดูแล) อธิบายว่า error ของ JavaScript ทุกตัวมี 2 ส่วน คือ ชื่อ ที่บอกชนิดของ error และ ข้อความ ที่อธิบายละเอียดขึ้น 2 ส่วนนี้รวมกันคือจุดเริ่มต้นของการเข้าใจและแก้ปัญหา
MDN ยังเขียนไว้ตรงๆ ว่า ปัญหาที่ error รายงาน ไม่ได้ชัดเจนทันทีเสมอไป นี่คือเหตุผลที่ต้องอ่าน error เป็น ไม่ใช่แค่คัดลอกส่งต่อ
3 อย่างที่ต้องหาในทุก error
| ส่วน | ถามว่า | หาที่ไหน |
|---|---|---|
| 1. ชนิด | ปัญหาแบบไหน | คำที่ลงท้ายด้วย Error เช่น TypeError และข้อความหลังเครื่องหมาย : |
| 2. ตำแหน่ง | เกิดที่ไฟล์ไหน บรรทัดไหน | ชื่อไฟล์ของคุณที่มีเลขบรรทัดต่อท้าย |
| 3. บริบท | เกิดตอนทำอะไร อะไรเพิ่งเปลี่ยน | ไม่มีบนจอ คุณต้องเขียนเอง |
ข้อ 1 และ 2 โปรแกรมบอกให้แล้ว ส่วนข้อ 3 มีแค่คุณที่รู้ และหลายครั้งข้อ 3 คือสิ่งที่ทำให้ AI แก้ได้ถูกจุด
ต่อไปลองดู error จริง 3 ตัว
ตัวอย่างที่ 1 (Node.js): ใบเสร็จออกได้ 2 ใบ แล้วพัง
สมมติ AI เขียนโปรแกรม receipt.js ให้ โปรแกรมนี้อ่านรายการออเดอร์จากไฟล์ orders.json แล้วพิมพ์ใบเสร็จทีละใบ เมื่อรัน ได้ผลดังนี้ เราย่อชื่อโฟลเดอร์ยาวๆ ข้างหน้าเป็น /…/ ให้อ่านง่าย ส่วนอื่นตรงตามที่ขึ้นจริง ยกเว้นจุดเดียวที่บอกไว้ใต้กล่อง
ใบเสร็จ #1 คุณสมชาย ยอด 450 บาท
ใบเสร็จ #2 คุณสมหญิง ยอด 120 บาท
/…/demo/receipt.js:6
console.log(`ใบเสร็จ #${order.id} คุณ${order.customer.name} ยอด ${order.total} บาท`);
^
TypeError: Cannot read properties of undefined (reading 'name')
at printReceipt (/…/demo/receipt.js:6:57)
at Array.forEach ([anonymous])
at Object.[anonymous] (/…/demo/receipt.js:9:8)
at Module._compile (node:internal/modules/cjs/loader:1734:14)
at Object..js (node:internal/modules/cjs/loader:1899:10)
at Module.load (node:internal/modules/cjs/loader:1469:32)
at Function._load (node:internal/modules/cjs/loader:1286:12)
at TracingChannel.traceSync (node:diagnostics_channel:322:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:235:24)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:151:5)
Node.js v23.11.0หมายเหตุ: ในข้อความจริง คำว่า anonymous (และ module ในตัวอย่าง Python) อยู่ในวงเล็บมุม หน้าเว็บนี้แสดงวงเล็บมุมไม่ได้ เราจึงเปลี่ยนเป็น [ ]
ชนิด: บรรทัด TypeError: Cannot read properties of undefined (reading 'name') แปลว่า โปรแกรมพยายามอ่านค่า name จากของที่ไม่มีอยู่ (undefined)
ตำแหน่ง: receipt.js:6 คือไฟล์ receipt.js บรรทัดที่ 6 ส่วนบรรทัดที่ขึ้นต้นด้วย at คือเส้นทางที่โปรแกรมเดินมาจนถึงจุดที่พัง ส่วนนี้มักเรียกว่า stack trace เอกสารของ Node.js อธิบายว่า error.stack ขึ้นต้นด้วยชื่อ error และข้อความ แล้วตามด้วยบรรทัด at ทีละจุดในโค้ดที่เรียกต่อกันมาจนเกิด error
บรรทัดที่มี node:internal เป็นโค้ดภายในของ Node.js เอง ไม่ใช่โค้ดของคุณ จึงข้ามไปได้ ให้มองหาชื่อไฟล์ของคุณแทน ในตัวอย่างนี้คือ receipt.js บรรทัด 6 และ 9
อย่ามองข้ามบรรทัดก่อน error: ใบเสร็จ #1 และ #2 พิมพ์ออกมาแล้ว แปลว่าโค้ดใช้ได้กับ 2 ออเดอร์แรก และพังที่ออเดอร์ถัดไป ในไฟล์ตัวอย่างของเรา ออเดอร์ที่ 3 ไม่มีข้อมูล customer เลย
บริบท (ข้อ 3) ทำให้ AI เสนอวิธีแก้ต่างกัน
เมื่อ 16 ตุลาคม 2569 เราลองส่ง error นี้ทั้งก้อนให้ Claude 2 แบบ
- แบบแรก พิมพ์แค่ "แก้ error นี้ให้หน่อย": Claude บอกสาเหตุได้ถูก แต่วิธีแรกที่มันแนะนำคือให้โค้ด ใส่ชื่อสำรองว่า "ลูกค้าทั่วไป" เมื่อไม่มีชื่อ ส่วนการกลับไปแก้ที่ข้อมูลเป็นทางเลือกที่สอง
- แบบที่สอง เพิ่มบริบทสั้นๆ ว่าเมื่อวานรันได้ปกติ และวันนี้เพิ่งเปลี่ยนไปใช้ไฟล์ออเดอร์ชุดใหม่ที่ export จากระบบหลังร้าน ซึ่งบังคับกรอกชื่อลูกค้าทุกออเดอร์ ครั้งนี้ Claude บอกว่าชื่อน่าจะยังอยู่ในไฟล์ แต่อยู่คนละที่กับที่โค้ดอ่าน จึงให้รันคำสั่งดูข้อมูลก่อน และเขียนเองว่าไม่ใช้วิธีใส่ค่าว่างแทน เพราะจะได้ใบเสร็จที่ไม่มีชื่อลูกค้าออกมาเงียบๆ
เรารันคำสั่งดูข้อมูลที่ Claude ให้มา ได้ {"id":3,"total":300} แปลว่าออเดอร์ที่ 3 ไม่มีชื่อลูกค้าเลย ไม่ได้อยู่คนละที่อย่างที่ Claude เดา Claude เดาผิดส่วนหนึ่งเพราะบริบทที่เราให้ (ระบบบังคับกรอกชื่อ) ไม่ตรงกับความจริงของไฟล์นี้ บริบทจึงต้องเป็นเรื่องจริงที่เรารู้แน่ แต่การดูข้อมูลก่อนก็ทำให้รู้ว่าต้องกลับไปถามระบบหลังร้าน ไม่ใช่ออกใบเสร็จที่ไม่มีชื่อลูกค้า
error เดียวกัน แต่ได้คำแนะนำแรกต่างกัน แบบแรกทำให้ error หายไป แบบที่สองพาไปหาสาเหตุ สิ่งที่ต่างกันคือบริบทสั้นๆ ที่มีแค่คุณรู้
เราลองกับ Claude แบบละ 1 ครั้ง ด้วยข้อมูลสมมติที่เราแต่งขึ้นเอง
ตัวอย่างที่ 2 (Python): บรรทัดที่ error ชี้ ไม่ใช่บรรทัดที่ต้องแก้เสมอ
โปรแกรมนี้รวมยอดขายจากไฟล์ sales.csv ที่มียอดขาย 3 วัน คือ 1200, 950 และ 1430
import csv
def read_sales(path):
with open(path, encoding="utf-8") as f:
return [row["ยอดขาย"] for row in csv.DictReader(f)]
def total(amounts):
result = 0
for a in amounts:
result += a
return result
sales = read_sales("sales.csv")
print("ยอดรวม:", total(sales))เมื่อรัน ได้ผลดังนี้
Traceback (most recent call last):
File "/…/demo/total.py", line 14, in [module]
print("ยอดรวม:", total(sales))
~~~~~^^^^^^^
File "/…/demo/total.py", line 10, in total
result += a
TypeError: unsupported operand type(s) for +=: 'int' and 'str'error ของ Python อ่านจากล่างขึ้นบนจะง่ายกว่า เพราะเอกสารของ Python อธิบายว่า บรรทัดสุดท้ายบอกว่าเกิดอะไรขึ้นและเป็น error ชนิดไหน ส่วนบรรทัดข้างบนคือเส้นทางที่โปรแกรมเดินมาจนถึงจุดนั้น เรียกว่า traceback
ชนิด: TypeError: unsupported operand type(s) for +=: 'int' and 'str' แปลว่า เอาตัวเลข (int) ไปบวกกับตัวหนังสือ (str) ไม่ได้
ตำแหน่ง: error ชี้บรรทัด 10 result += a แต่บรรทัด 10 ไม่ได้ผิด ที่มาของปัญหาคือบรรทัด 5 ที่อ่านยอดขายจากไฟล์มาเป็นตัวหนังสือ "1200" โดยไม่ได้แปลงเป็นตัวเลข
เอกสารของ Python เตือนไว้ในหัวข้อ error ไวยากรณ์ (SyntaxError) ว่าจุดที่ error ชี้ ไม่ใช่จุดที่ต้องแก้เสมอไป ตัวอย่างนี้แสดงว่าเรื่องเดียวกันเกิดกับ error ชนิดอื่นได้ด้วย
เราลองแก้บรรทัด 5 เป็น int(row["ยอดขาย"]) แล้วรันใหม่ ได้ ยอดรวม: 3580 ตรงกับที่คิดเลขเอง ถ้าไปแก้ที่บรรทัด 10 แทน error ก็น่าจะหายเหมือนกัน แต่ส่วนอื่นของโปรแกรมที่ใช้ sales จะยังได้ยอดขายเป็นตัวหนังสืออยู่ (ข้อนี้เราอ่านจากโค้ด ไม่ได้ลองรัน)
ตัวอย่างที่ 3 (Python): โค้ดเดิม ไฟล์เดิม แต่พัง
ใช้โปรแกรมเดียวกับตัวอย่างที่ 2 และไฟล์ sales.csv ยังอยู่ที่เดิม แต่คราวนี้เปิดหน้าต่างพิมพ์คำสั่ง (terminal) ใหม่ แล้วรันจากโฟลเดอร์อื่น ได้ผลดังนี้
Traceback (most recent call last):
File "/…/demo/total.py", line 13, in [module]
sales = read_sales("sales.csv")
File "/…/demo/total.py", line 4, in read_sales
with open(path, encoding="utf-8") as f:
~~~~^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'sales.csv'ชนิด: FileNotFoundError แปลว่า หาไฟล์ sales.csv ไม่เจอ
ตำแหน่ง: บรรทัด 4 ที่เปิดไฟล์
ถ้าอ่านแค่ 2 ข้อนี้ ข้อสรุปที่ง่ายที่สุดคือ "ไม่มีไฟล์" แต่คุณรู้ว่าไฟล์มีอยู่ บริบทในกรณีนี้คือ "รันจากในโฟลเดอร์นั้นได้ แต่รันจากที่อื่นแล้วพัง" บริบทนี้ชี้ไปที่สาเหตุจริง คือชื่อไฟล์ "sales.csv" ที่ไม่มีที่อยู่เต็มจะถูกหาจากโฟลเดอร์ที่ terminal เปิดอยู่ ไม่ใช่โฟลเดอร์ที่โปรแกรมอยู่
เราลองแล้ว เมื่อรันจากในโฟลเดอร์ที่มีไฟล์ โปรแกรมทำงานปกติ เมื่อรันจากโฟลเดอร์อื่น ได้ error ข้างบน
ส่ง error ให้ AI ใน 4 ขั้น
1. อ่านเองก่อน 1 นาที
หาชนิดและตำแหน่งของ error แม้จะอ่านไม่ออกทั้งหมด แค่รู้ว่าพังที่ไฟล์ไหน บรรทัดไหน ก็พอจะเช็กได้ว่า AI แก้ตรงจุดหรือไม่ หรือไปแก้ไฟล์อื่นที่ไม่เกี่ยวข้อง
2. คัดลอก error มาทั้งก้อน ไม่ตัดส่วนใดออก
คัดลอกบรรทัดที่ขึ้นก่อน error มาด้วย เช่น ใบเสร็จ 2 ใบในตัวอย่างที่ 1 ซึ่งบอกว่าพังที่รายการไหน ถ้าตัดเหลือแค่บรรทัดเดียว AI จะเห็นแค่ชนิด แต่ไม่เห็นตำแหน่งและเส้นทาง
มีข้อยกเว้นเดียว คือถ้าใน error มีรหัสผ่าน กุญแจ API หรือข้อมูลลูกค้าปรากฏอยู่ ให้แทนด้วย [ลบแล้ว] ก่อนวาง
3. เขียนบริบท 3 บรรทัด
ตอบ 3 คำถามนี้สั้นๆ
- กำลังทำอะไรตอนเกิด
- เคยใช้ได้ไหม
- อะไรเปลี่ยนไปก่อนเกิด ถ้าไม่รู้ให้เขียนว่าไม่รู้ อย่าเดา
4. สั่งให้อธิบายก่อนแก้
ให้ AI อธิบายก่อนว่า error แปลว่าอะไร แล้วค่อยเสนอวิธีแก้ และให้บอกด้วยถ้าวิธีแก้แค่ทำให้ error หายไป แต่ไม่ได้แก้ที่ต้นเหตุ อย่างการใส่ชื่อสำรองในตัวอย่างที่ 1
คำสั่งสำเร็จรูปสำหรับส่ง error ให้ AI
คำสั่งนี้รวม 4 ขั้นข้างบนไว้ในที่เดียว เติมข้อความในวงเล็บเหลี่ยมให้ตรงกับงานของคุณ
error นี้เกิดตอน: [กำลังทำอะไร เช่น สั่งพิมพ์ใบเสร็จ] ก่อนหน้านี้เคยใช้ได้ไหม: [ได้ / ไม่เคยได้เลย] สิ่งที่เปลี่ยนไปก่อนเกิด: [เช่น เปลี่ยนไฟล์ข้อมูล อัปเดตโปรแกรม / ไม่รู้] ที่ฉันอ่านเอง: ชนิด = [...] · ตำแหน่ง = ไฟล์ [...] บรรทัด [...] ช่วยอธิบายเป็นภาษาง่ายๆ ว่า error นี้แปลว่าอะไร และน่าจะเกิดจากอะไร ก่อนเสนอวิธีแก้ ถ้าต้นเหตุไม่ได้อยู่บรรทัดที่ error ชี้ ให้บอกว่าอยู่ตรงไหน ถ้าวิธีแก้แค่ทำให้ error หายแต่ซ่อนปัญหาไว้ เช่น ใส่ค่าว่างหรือค่าสำรองแทน ให้บอกตรงๆ """ [วาง error ทั้งก้อน ไม่ตัด] """
แต่ละส่วนของคำสั่งช่วยอะไร
- 3 บรรทัดแรกคือบริบทที่ AI เดาเองไม่ได้
- "ที่ฉันอ่านเอง" ทำให้คุณได้ฝึกอ่าน error
- การให้อธิบายก่อนแก้ ทำให้ตรวจเหตุผลได้ก่อนรับโค้ด
- ข้อสุดท้ายป้องกันวิธีแก้แบบกลบอาการ
ถ้าอยากได้ฉบับเต็มที่ให้ AI ตั้งสมมติฐานหลายข้อ พร้อมวิธีพิสูจน์แต่ละข้อก่อนแก้ ดูได้ที่ prompt ฟรี: หาต้นตอของ Bug จาก Error โดยตรวจสอบให้แน่ใจก่อนลงมือแก้ (สำหรับสมาชิกฟรี)
3 เรื่องที่ควรรู้เพิ่มเติม
- ข้อความ error ต่างกันตามโปรแกรม MDN ยกตัวอย่างว่า ความผิดพลาดแบบเดียวกัน โปรแกรมที่ใช้ V8 (เช่น Chrome และ Node.js) และ Firefox จะขึ้นว่า
ReferenceError: "x" is not definedแต่ Safari จะขึ้นว่าReferenceError: Can't find variable: xชนิดของ error จึงเชื่อถือได้มากกว่าถ้อยคำ - บางครั้งเส้นทางไม่มีไฟล์ของคุณเลย เช่น โปรแกรมพังข้างในโปรแกรมเสริมที่ติดตั้งมา กรณีนี้ข้อ 3 (บริบท) สำคัญที่สุด ให้บอกว่าคุณกดอะไรหรือสั่งอะไรก่อนเกิด error
- AI ก็อ่าน error ผิดได้ ถ้า AI ไปแก้ไฟล์หรือบรรทัดที่ไม่ตรงกับที่คุณอ่านเจอ ให้ถามว่าทำไมก่อนรับโค้ด
สรุป
error มี 3 ส่วนที่ต้องหา คือ ชนิด ตำแหน่ง และบริบท 2 อย่างแรกอยู่บนจอ อย่างที่ 3 อยู่ในหัวคุณ ก่อนส่งให้ AI ให้อ่านเองก่อน 1 นาที คัดลอกมาทั้งก้อน เขียนบริบท 3 บรรทัด แล้วให้ AI อธิบายก่อนแก้
ตอนถัดไปในซีรีส์ว่าด้วย Git ซึ่งเป็นเหมือนจุดเซฟเกมของคนเขียนโค้ด ถ้าแก้ตาม AI แล้วพังกว่าเดิม Git ช่วยให้ย้อนกลับไปจุดที่ยังใช้ได้
อ่านต่อเรื่องโค้ดที่ AI เขียนได้ที่ ให้ AI เขียนโค้ดแทนแล้ว ยังต้องสนใจไหมว่าโค้ดดีหรือไม่ดี (สำหรับสมาชิกฟรี)
อาทิตย์ละสกิล เดี๋ยวก็เก่ง