สคริปต์อัตโนมัติ (Automation Script) คือตัวช่วยที่หลายธุรกิจใช้อยู่ทุกวัน ทั้งการสรุปยอดขายประจำวัน การส่งรายงานเข้ากลุ่มไลน์ การดึงข้อมูลจาก API ของคู่ค้า หรือการบันทึกข้อมูลเซนเซอร์จากเครื่องจักร มันช่วยประหยัดเวลาและแรงคนได้มหาศาล แต่ปัญหาที่เจอบ่อยที่สุดไม่ใช่ "สคริปต์ทำงานไม่ได้" แต่คือ "สคริปต์พังเงียบ ๆ" — วิ่งต่อไปทุกวันตามกำหนด แต่ผลลัพธ์ที่ได้ผิดพลาดหรือว่างเปล่า จนกว่าจะมีใครสังเกตเห็น
บทความนี้รวบรวมข้อผิดพลาดที่เราพบจริงจากการพัฒนาและดูแลระบบของลูกค้า โดยมองผ่านสายตาของทั้งเจ้าของธุรกิจและนักพัฒนาที่ต้องเผชิญปัญหาในสนามจริง
1. กลืน Exception ไว้ใน try-except แบบไม่มีใครรู้
รหัสแบบนี้พบได้บ่อยมากในสคริปต์ที่ถูกเขียนขึ้นแบบเร่งรีบ:
try:
data = fetch_data()
save_to_db(data)
except Exception:
pass
การเขียนแบบนี้ทำให้สคริปต์ "ไม่เคยพัง" แต่ก็ "ไม่เคยสำเร็จ" ด้วยเช่นกัน เพราะเมื่อข้อมูลไม่ได้ถูกบันทึก ก็จะไม่มีข้อผิดพลาดหลุดออกมาให้เห็น ทีมจะรู้ตัวอีกทีก็ตอนที่ตัวเลขในรายงานไม่ตรงกับความจริง
หลักการง่าย ๆ คือ จับข้อผิดพลาดเฉพาะเจาะจง (เช่น FileNotFoundError, ConnectionError) แทนการจับ Exception ทั้งหมดแบบครอบจักรวาล และในทุกจุดที่จับข้อผิดพลาดได้ ต้องเขียน log เอาไว้เสมอ
2. Hardcode Path และ Credential ไว้ในไฟล์
เส้นทางไฟล์หรือรหัสผ่านที่ถูกเขียนตายตัวในสคริปต์สร้างปัญหาใหญ่สองแบบ แบบแรกคือ เมื่อย้ายไปรันบนเครื่องอื่นหรือ server ใหม่ สคริปต์จะหาไฟล์ไม่เจอแล้วพังแบบไม่มีทางรู้ แบบที่สองคือ รหัสผ่านที่หลุดเข้าไปใน git history ซึ่งแก้ไขกลับไม่ได้
วิธีที่ถูกต้องคือ ใช้ environment variable หรือไฟล์ .env ในการเก็บค่าเหล่านี้ และเพิ่ม .env เข้าไปใน .gitignore เสมอ เพื่อให้ทั้งความปลอดภัยและความยืดหยุ่นไปด้วยกัน
3. สคริปต์ไม่รองรับการรันซ้ำ (Idempotency)
สคริปต์อัตโนมัติส่วนใหญ่ถูกกำหนดให้รันเป็นรอบ เช่น ทุกเที่ยงคืน แต่เมื่อเกิดเหตุการณ์ที่ต้องรันซ้ำ เช่น server รีสตาร์ทกลางทาง หรือ cron รันสองรอบ สคริปต์ที่ไม่คิดเรื่องนี้จะสร้างข้อมูลซ้ำ เช่น บันทึกยอดขายวันเดียวกันสองครั้ง ทำให้ตัวเลขในรายงานบวมขึ้นอย่างน่าเกลียด
แนวทางแก้คือ ออกแบบให้การรันครั้งที่สอง "ทับ" ผลลัพธ์ครั้งแรกได้ เช่น ใช้ unique constraint ในฐานข้อมูล หรือใช้กลไก upsert เพื่อให้สคริปต์รันกี่ครั้งก็ได้ผลลัพธ์เท่าเดิม
4. ลืมคิดเรื่องเวลาและ Timezone
ปัญหาที่ดูเล็กแต่สร้างความปวดหัวมหาศาล คือ การบันทึกเวลาเป็นเวลาท้องถิ่นของเครื่อง server โดยไม่ระบุ timezone เมื่อใดก็ตามที่ server ตั้งเวลาเพี้ยนหรือย้ายเครื่องไปต่างโซน ข้อมูลเวลาในระบบจะเลื่อนเพี้ยนไปทั้งชุด กระทบการคำนวณยอดรายวันและรายเดือน
หลักปฏิบัติคือ เก็บเวลาเป็น UTC ในฐานข้อมูลเสมอ แล้วค่อยแปลงเป็นเวลาท้องถิ่นตอนแสดงผลหรือส่งรายงาน ซึ่งไลบรารีอย่าง pendulum หรือ zoneinfo ใน Python จัดการได้สะดวก
5. ไม่มี Logging และระบบแจ้งเตือน
สคริปต์พังตอนตีสาม แต่ไม่มีใครรู้จนกระทั่งลูกค้าโทรมาถามตอนเช้า ปัญหานี้เกิดจากการที่สคริปต์ไม่มีหลักฐานว่ามันทำอะไร ทำสำเร็จหรือไม่ และไม่มีการแจ้งเตือนเมื่อเกิดความผิดปกติ
ทางที่ทำได้จริงคือ ใช้ logging module ของ Python เขียน log ไปยังไฟล์หรือระบบรวมศูนย์ และเพิ่มการแจ้งเตือนผ่าน LINE Notify, Email หรือแพลตฟอร์มอื่น ๆ ในจุดที่จับข้อผิดพลาดได้ เพื่อให้ทีมรู้ภายในไม่กี่นาทีหลังเกิดปัญหา ไม่ใช่ไม่กี่วัน
6. ไม่ใช้ Virtual Environment และไม่ Pin เวอร์ชัน Library
สถานการณ์คลาสสิก คือ สคริปต์ที่เคยรันได้ปกติ จู่ ๆ ก็พังหลัง pip install package ตัวใหม่ เพราะไลบรารีถูกอัปเดตเวอร์ชันแบบไม่ตั้งใจ การไม่แยก environment ของแต่ละโปรเจกต์ทำให้การอัปเดตหนึ่งส่งผลกระทบไปทั้งระบบ
ควรสร้าง virtual environment แยกต่อโปรเจกต์ และบันทึกเวอร์ชันที่ทดสอบแล้วไว้ใน requirements.txt หรือ pyproject.toml พร้อมทดสอบการติดตั้งจากไฟล์นี้ในเครื่องสะอาดอย่างน้อยปีละครั้งเพื่อความมั่นใจ
7. ละเลย Encoding — ปัญหาที่คนไทยเจอประจำ
การอ่านไฟล์ CSV หรือ Excel จากหน่วยงานอื่น เช่น ธนาคารหรือกรมสรรพากร ซึ่งมักเข้ารหัสเป็น cp874 หรือ cp1252 แล้วนำมาเปิดด้วย encoding มาตรฐานของ Python (utf-8) จะได้ข้อความภาษาไทยเป็นตัวอักษรประหลาดทั้งชุด ข้อผิดพลาดที่ดูเล็กนี้ทำลายความน่าเชื่อถือของรายงานทั้งฉบับได้
วิธีป้องกันคือ ระบุ encoding อย่างชัดเจนตอนเปิดไฟล์ เช่น open(path, encoding="cp874") และเพิ่มการตรวจสอบก่อนประมวลผล เช่น ถ้าพบตัวอักษรที่ไม่รู้จัก ให้หยุดแล้วแจ้งเตือน แทนที่จะปล่อยให้ข้อมูลเสียผ่านเข้าไปในระบบ
8. ไม่คิดเรื่องการรันทับซ้อน (Overlapping Runs)
สคริปต์ที่ประมวลผลนานกว่าช่วงเวลาที่กำหนดไว้ เช่น กำหนดรันทุก 5 นาที แต่แต่ละรอบใช้เวลา 10 นาที จะทำให้สองรอบวิ่งพร้อมกัน แข่งกันอ่านและเขียนข้อมูลเดิมจนเกิดผลลัพธ์ที่คาดเดาไม่ได้
วิธีแก้ที่นิยมคือ ใช้ไฟล์ lock หรือใช้ระบบ queue อย่าง Celery และ RabbitMQ ในการจัดคิวงานแทนการรันแบบ cron ตรง ๆ ซึ่งระบบที่ใช้จริงในโปรดักชันควรออกแบบตั้งแต่แรก
จากสคริปต์เดี่ยว สู่ฮาร์ดแวร์: กรณี Arduino และ Industrial IoT
เมื่อสคริปต์ไม่ได้ดึงข้อมูลจาก API อย่างเดียว แต่ต้องคุยกับฮาร์ดแวร์จริง ๆ อย่าง Arduino หรือเซนเซอร์ในโรงงาน (Industrial IoT) ข้อผิดพลาดด้านบนยิ่งสำคัญมากขึ้น และยังมีปัญหาที่เฉพาะทางเพิ่มเข้ามาอีก เช่น การ hardcode พอร์ต USB อย่าง /dev/ttyUSB0 ซึ่งตำแหน่งอาจเปลี่ยนไปมาเมื่อรีบูตเครื่อง การไม่รองรับสายหลุดหรืออุปกรณ์ offline ชั่วคราว และการไม่ตรวจสอบหน่วยของค่าที่อ่านได้จากเซนเซอร์ เช่น องศาเซลเซียสหรือฟาเรนไฮต์ ค่าแรงดันที่ต้องแปลงเป็นเปอร์เซ็นต์
สำหรับใครที่อยากเริ่มต้นใช้ Arduino หรือเริ่มต้น Industrial IoT ให้ได้ผลจริง คำแนะนำจากโปรเจกต์จริงคือ อย่าเริ่มจาก "ซื้ออุปกรณ์ให้ครบทั้งโรงงาน" แต่ให้เริ่มจาก "ปัญหาหนึ่งปัญหาที่ทีมเจอจริง" เช่น การตรวจจับอุณหภูมิของตู้เซิร์ฟเวอร์หรือมอเตอร์ กำหนดให้อุปกรณ์ส่งข้อมูลผ่านโปรโตคอลมาตรฐานอย่าง MQTT แล้วให้สคริปต์ Python ทำหน้าที่เก็บข้อมูล ตรวจสอบความผิดปกติ และแจ้งเตือนผ่าน LINE หรืออีเมล การเริ่มแบบนี้ใช้เงินน้อย เรียนรู้ได้จริง และพิสูจน์ผลได้ภายในไม่กี่สัปดาห์ ก่อนที่จะขยายไปยังเซนเซอร์หลายสิบตัวทั้งโรงงาน
เช็กลิสต์ก่อนปล่อยสคริปต์ทำงานจริง
- ทุกจุดที่จับข้อผิดพลาดต้องมี log และมีการแจ้งเตือนเมื่อเกิดความผิดปกติ
- path, credential และค่าคงที่อื่น ๆ ต้องไม่อยู่ในโค้ด
- ทดสอบการรันซ้ำสองรอบแล้วผลลัพธ์ต้องเท่าเดิม
- บันทึกเวลาเป็น UTC และตรวจสอบ encoding ของข้อมูลนำเข้าทุกครั้ง
- ใช้ virtual environment พร้อม pin เวอร์ชันไลบรารี
- ออกแบบป้องกันการรันทับซ้อนตั้งแต่วันแรกที่เขียน
- ถ้าเกี่ยวข้องกับฮาร์ดแวร์ ให้ทดสอบการหลุดของอุปกรณ์และการ reconnect อย่างสม่ำเสมอ
สคริปต์อัตโนมัติที่ดีไม่จำเป็นต้องซับซ้อน แต่ต้อง "อยู่รอดได้ในโลกจริง" — เจอข้อมูลผิดปกติได้ ระบบพังได้ แต่ต้องรู้ตัวและกู้คืนได้เร็ว สิ่งเหล่านี้เป็นประสบการณ์ที่ได้มาจากการทำงานจริงมากกว่าหนังสือเรียน
ถ้าธุรกิจของคุณกำลังจะสร้างระบบอัตโนมัติ ไม่ว่าจะเป็นสคริปต์ประมวลผลข้อมูล ระบบเชื่อมต่อเซนเซอร์ Arduino หรือ Industrial IoT ไปจนถึงแพลตฟอร์มเว็บไซต์เต็มรูปแบบที่ต้องทำงานร่วมกันอย่างเสถียร ทีม pythonthailand.com (Para-Studio เชียงใหม่) มีประสบการณ์พัฒนาเว็บไซต์ด้วย Python-Django และระบบ AI อัตโนมัติที่ออกแบบให้รองรับการใช้งานจริงในระยะยาว เราสามารถช่วยวางสถาปัตยกรรมและดูแลระบบหลังการส่งมอบได้เช่นกัน หากสนใจพูดคุยแลกเปลี่ยนมุมมอง ทักมาที่หน้า /contact ได้เลยครับ
หากชอบบทความดีๆ โปรดติดตามพวกเราด้วยนะคะ 🙏