Custom Error Handling for ObjectMapper

ผมเคยเขียนถึง Model Mapper Library ชื่อ Mantle เมื่อนานมาแล้ว ตอนเขียน Objective-C
ชอบมากเลยตอนนั้น สบายขึ้นเยอะ แต่พอมาเขียน Swift ก็หาอะไรที่คล้ายและเก่งเท่า Mantle ไม่ได้เลย

ผมลองหลายตัวจนมาจบที่ ObjectMapper และผมใช้คู่กับ Network Library ชื่อดังอย่าง Alamofire ซึ่งมีคนทำ Extension ครอบไว้ให้เลยคือตัวนี้ AlamofireObjectMapper ทำให้เมื่อเราขอข้อมูลจาก API ผ่าน Network แล้วโค้ดที่ได้ก็จะหน้าตาประมาณนี้เลย

Wait for the Code ....

จะเห็นว่าส่วนของ JSON Parser จะไม่อยู่ที่นี่ แต่มีเพียงโค้ดที่เราทำการขอข้อมูลจาก API และพ่นออกมาเป็น Object ให้เราเลย คราวนี้พอเราแงะเข้าไปดูใน AlamofireObjectMapper นั้น หน้าที่ของการทำ json parsing จะอยู่ที่การเขียน Extension ของ Request class ของ Alamofire เพื่อทำ Custom Serializer  ระหว่างที่เซิฟเวอร์ส่งข้อมูลกลับมาให้เรา

Wait for the Code ....


บางคนอาจจะไม่มีปัญหากับโค้ดนี้ แม้กระทั่งผมจนพบว่า มีปัญหาหว่ะ...
นั่นคือจังหวะของการ parse error จากเซิฟเวอร์ซึ่งคนเขียน Extenstion นี้ไม่ได้เขียนในส่วนของการจัดการ Custom Error ที่มาจากเซิฟเวอร์ จึงทำให้เวลาเกิด Error แล้วเราส่งให้แสดงผ่าน UIAlertController นั้น ข้อความที่ถูกแสดงก็จะเป็น "ObjectMapper failed to serialize response." ตลอดเวลา

คราวนี้จะแก้ยังไงล่ะ ผมใช้โค้ดต้นแบบจาก Extension นี้มาเขียนแก้ไขอีกครั้งเพื่อให้รองรับการทำ Custom Error จากฝั่งเซิฟเวอร์ โดยตัวอย่าง Error ที่จะถูกส่งกลับมาจะเป็นรูปแบบนี้

Wait for the Code ....

เมื่อเรามองดูจาก json ด้านบน ก่อนอื่นผมจะสร้าง Protocol สำหรับ json ของ Error นี้ก่อนโดยใช้ชื่อว่า APIError แล้วเขียน class ที่ conform protocol นี้เพื่อที่จะทำการแปลงผลลัพธ์ของ error ดังกล่าวมาอยู่ในรูปของ object ที่เราสามารถเรียกใช้ได้โดยง่าย

Wait for the Code ....

ในส่วนของ Extension เต็มๆ เดี๋ยวผมเอาให้ดูตอนหลังสุดละกันนะครับ ตอนนี้อยากให้เข้าใจวิธีการที่ผมใช้ซะก่อน เมื่อเราได้ Error protocol, class มาแล้ว เราก็จะมา override static method (class method) ที่ชื่อว่า ObjectMapperSerializer บน Request class เพื่อบอกวิธีการในการจัดการ json ที่เข้ามา และ method responseObject ที่เราใช้เรียกผ่าน Alamofire ก็จะได้ประมาณนี้

Wait for the Code ....

โดยสิ่งที่ผมเพิ่มเข้ามาก็คือ Generic Type Identifier เพื่อบอกว่าเราจะมีการใช้ E type ที่ conform APIError protocol นะ จากนั้นให้แต่ละ method รับ ErrorType เข้ามา ว่าจะให้ parse เป็น instance ของ class ไหนเพื่อนำไปเรียกใช้ในภายหลัง (ใช้เพื่อเปลี่ยนเป็น NSError)

ในส่วนของเนื้อหาของการ parse นั้นจะมีโค้ดส่วนหนึ่งที่จะทำการ parse error ของเราและ mapping กับ class ที่เราระบุมาตอนต้น โดยอ้างอิงจาก statusCode ของเซิฟเวอร์ที่ไม่อยู่ระหว่าง 200 และ 400 นั่นเอง

Wait for the Code ....

คราวนี้พอมาดูวิธีการเรียกใช้งานก็จะประมาณนี้ครับ
โดยผลลัพธ์เมื่อเซิฟเวอร์ส่ง error กลับมาก็จะได้เป็น object ของ NSError ที่มี error message ที่ถูกต้องแล้วล่ะ

Wait for the Code ....

อันนี้เป็น Extension ที่ผมเขียนเต็มๆ ครับ (โดยเพิ่มส่วน Array Parsing ไปด้วย)
แถมการจัดการในกรณีที่ Server ส่ง empty response โดย status code เป็น 204 ด้วย (เพราะถ้าใช้ตามปกติเลย มันจะโยน .Failed ออกมาแทนในกรณีที่ data เป็น nil)

Wait for the Code ....

วันนี้พอก่อนละกันครับ พบกันใหม่ตอนหน้า
ตอนแรกก็คิดว่าจะไม่ยาว แต่พอเขียนจริงๆ แล้วยาวเหมือนกันแหะ

ใครสงสัยอะไรก็มาคุยกันได้นะครับ :) ถ้าผมอธิบายตรงไหนไม่ค่อยเคลียร์

Comments

Popular posts from this blog

12 วิธี การบริการและดูแลลูกค้าในร้าน Starbucks

Command Line Compiling C/C++ ,Java [Windows, Mac]

การเขียนโปรแกรมแก้ปัญหา "โจทย์รูปทรงสมมาตร"