ทำให้การระงับข้อผิดพลาดของ Flow มีความเฉพาะเจาะจงมากขึ้น

Mar 19 2020
เรากำลังปรับปรุงการระงับข้อผิดพลาดของ Flow เพื่อไม่ให้ซ่อนข้อผิดพลาดโดยไม่ได้ตั้งใจ ในปีหน้า Flow กำลังวางแผนที่จะเปลี่ยนแปลงและปรับปรุงระบบประเภทต่างๆมากมาย
ภาพถ่ายโดย icon0.com จาก Pexels

เรากำลังปรับปรุงการระงับข้อผิดพลาดของ Flow เพื่อไม่ให้ซ่อนข้อผิดพลาดโดยไม่ได้ตั้งใจ

ในปีหน้า Flow กำลังวางแผนที่จะเปลี่ยนแปลงและปรับปรุงระบบประเภทต่างๆมากมาย อย่างไรก็ตามผลที่ตามมาประการหนึ่งคือคุณอาจต้องเพิ่มการระงับลงในโค้ดของคุณเนื่องจาก Flow จะค้นหาปัญหาที่มีอยู่ได้ดีขึ้น

ซึ่งอาจเป็นปัญหาได้เนื่องจากการระงับของ Flow ส่งผลมากกว่าข้อผิดพลาดเดิมที่คุณตั้งใจจะระงับ ซึ่งจะช่วยลดความสามารถของ Flow ในการตรวจจับข้อผิดพลาด นี่เป็นผลมาจากคุณสมบัติสองประการ: ประการแรกการระงับการไหลสามารถอยู่ที่ส่วนใดก็ได้ของข้อผิดพลาดประเภทและประการที่สองการระงับการไหลสามารถระงับข้อผิดพลาดประเภทใดก็ได้ ในการแก้ไขข้อบกพร่องเหล่านี้เราจะกำหนดให้วางการระงับไว้ที่ตำแหน่งในรหัสของคุณที่เกิดข้อผิดพลาดจริงและรวมถึงรหัสข้อผิดพลาดที่ระบุประเภทของข้อผิดพลาดที่คุณต้องการระงับ

เพื่อให้เข้าใจว่าทั้งหมดนี้หมายถึงอะไรเรามาดูลักษณะของข้อผิดพลาดประเภทของ Flow

ข้อผิดพลาดประเภทคืออะไร?

เมื่อ Flow พบปัญหาในขณะตรวจสอบโค้ดของคุณเช่นความเข้ากันไม่ได้ระหว่างสองประเภทหรือการเข้าถึงคุณสมบัติที่ไม่ถูกต้องจะสร้างข้อผิดพลาดที่รายงานให้ผู้ใช้ทราบอย่างแม่นยำว่ามีอะไรผิดปกติกับรหัสของพวกเขา ข้อผิดพลาดเหล่านี้อาจมีข้อมูลหลากหลายขึ้นอยู่กับสถานการณ์เฉพาะที่ทำให้เกิดข้อผิดพลาดแต่สองข้อที่เราให้ความสำคัญมากที่สุดคือประเภทของข้อผิดพลาดและตำแหน่งของข้อผิดพลาด ชนิดของข้อผิดพลาด encodes ลักษณะเฉพาะของพฤติกรรมที่ไม่ดีที่ตรวจพบการไหลในรหัสของคุณไม่ว่าจะเป็นสิ่งที่ง่ายเหมือนที่ผ่านการขัดแย้งมากเกินไปที่จะฟังก์ชั่นหรือบางสิ่งบางอย่างที่ซับซ้อนเช่นการแพร่กระจายชนิดสหภาพ ข้อมูลนี้จะบอก Flow ว่าจะแสดงข้อมูลประเภทใดให้กับผู้ใช้เพื่อให้อธิบายได้ดีที่สุดว่าคุณผิดพลาดตรงไหน สถานที่ของข้อผิดพลาดมีข้อมูลเกี่ยวกับข้อผิดพลาดที่ตั้งอยู่ในรหัสของคุณ มีสถานที่ตั้งสองประเภทที่อาจมีข้อผิดพลาดตำแหน่งหลัก (ซึ่งสามารถมีได้เพียงแห่งเดียว) และสถานที่รองซึ่งอาจมีได้หลายแห่งหรือไม่มีเลย ตำแหน่งหลักโดยประมาณสอดคล้องกับตำแหน่งในโค้ดของคุณที่เกิดข้อผิดพลาดจริงในขณะที่ตำแหน่งรองจะมีข้อมูลเกี่ยวกับไซต์คำจำกัดความของประเภทและค่าที่เกี่ยวข้องกับข้อผิดพลาด ตัวอย่างเช่น:



function foo(x : number) : void {}
foo("hello");
/* error */
foo("hello");
       ^ Cannot call `foo` with `"hello"` bound to `x` because string [1] is incompatible with number [2].
References:
2: foo("hello");
       ^ [1]
1: function foo(x : number) : void {}
                    ^ [2]

function foo(x : number) : void {}
let y : string = "hello";
foo(y);
/* error */
foo(y);
       ^ Cannot call `foo` with `y` bound to `x` because string [1] is incompatible with number [2].
References:
2: let y : string = "hello";
           ^ [1]
1: function foo(x : number) : void {}
                    ^ [2]

มีอะไรผิดปกติกับการปราบปราม?

เนื่องจากการระงับสามารถใช้ได้กับทั้งสถานที่หลักและรองการ//$FlowFixMeแสดงความคิดเห็นเหนือคำจำกัดความของfooจะระงับข้อผิดพลาดในทั้งสองตัวอย่างข้างต้น เนื่องจากfooปรากฏเป็นตำแหน่งรองในทุกข้อผิดพลาดที่ใช้จึงหมายความว่าการใช้งานใด ๆfooที่ทำให้เกิดข้อผิดพลาดจะถูกระงับโดยการปราบปรามนี้ทุกที่ที่อาจเกิดขึ้น คุณสามารถโทรfooด้วยอาร์กิวเมนต์ประเภทใดก็ได้และ Flow จะไม่แสดงข้อผิดพลาดหรือคำเตือนใด ๆ ให้คุณเกี่ยวกับสิ่งนี้ สิ่งนี้ทำให้ความเชื่อมั่นของผู้ใช้ลดลงในการตรวจสอบประเภทของ Flow และอนุญาตให้มีข้อบกพร่องที่อาจทำให้เกิดการผลิตได้

นอกจากนี้การระงับของ Flow จะส่งผลกระทบต่อข้อผิดพลาดทุกประเภทตราบเท่าที่มีตำแหน่งที่การปราบปรามครอบคลุม ซึ่งหมายความว่าสามารถระงับข้อผิดพลาดหลายประเภทได้โดยการปราบปรามเพียงครั้งเดียว หากต้องการดูอันตรายในสิ่งนี้ให้พิจารณาตัวอย่างต่อไปนี้:

// library file lib.js
function foo(x : number) : void {}
// impl file
const {foo} = require("lib.js");
let y : string = "hello";
// $FlowFixMe
foo(y);

เราจะทำอย่างไรกับเรื่องนี้?

เพื่อแก้ไขปัญหานี้เราจะทำการเปลี่ยนแปลงต่อไปนี้:

  • บังคับใช้สถานที่หลัก เราจะเปลี่ยนพฤติกรรมการปราบปรามเพื่อให้การปราบปรามใช้กับข้อผิดพลาดเมื่อวางไว้ที่ตำแหน่งหลักเท่านั้น ตัวอย่างเช่นแทนที่จะอนุญาตให้คุณระงับการโทรที่ไม่ถูกต้องตามคำจำกัดความของฟังก์ชันตอนนี้เราต้องการให้การปราบปรามอยู่ที่ไซต์การโทรเอง วิธีนี้ Flow จะยังคงสามารถแจ้งเตือนคุณเกี่ยวกับการเรียกฟังก์ชันอื่น ๆ ที่อาจไม่ถูกต้องได้
  • เพิ่มรหัสข้อผิดพลาด นอกจากนี้เราจะเพิ่มรหัสข้อผิดพลาดในการปราบปรามของเราดังนั้นจึงระงับเฉพาะข้อผิดพลาดประเภทที่ระบุเท่านั้น วิธีนี้จะป้องกันการระงับจากการระงับข้อผิดพลาดที่คุณไม่คาดคิดโดยไม่คาดคิด
  • สร้างมาตรฐานไวยากรณ์การปราบปราม ก่อนหน้านี้ไวยากรณ์ที่ยอมรับได้สำหรับการระงับข้อผิดพลาดสามารถกำหนดค่าได้ด้วยตนเองใน.flowconfigสำหรับโปรเจ็กต์ที่กำหนดทำให้ไวยากรณ์การปราบปรามที่ไม่สอดคล้องกันระหว่างโปรเจ็กต์ จากการเปลี่ยนแปลงข้างต้นเราจะกำหนดมาตรฐานของไวยากรณ์การปราบปราม รองรับเฉพาะรูปแบบ$FlowFixMe[incompatible-type]หรือ$FlowExpectedError[incompatible-type]

การเปิดตัว

เราตระหนักดีว่าการเปลี่ยนแปลงนี้อาจทำให้ข้อผิดพลาดจำนวนมากในฐานรหัสของคุณไม่ถูกต้องโดยเฉพาะอย่างยิ่งหากคุณมีนิสัยชอบวางการระงับในโค้ดไลบรารี เพื่อลดภาระนี้เรามีคำแนะนำสองสามข้อ:

  • หากต้องการย้ายการปราบปรามที่เพิ่งไม่ถูกต้องไปยังตำแหน่งหลักเราขอแนะนำให้ใช้ยูทิลิตี้add-commentsและremove-commentsยูทิลิตี้ที่มีให้ในเครื่องมือโฟลวร่วมกัน การเรียกใช้./tool remove-commentsจะลบความคิดเห็นที่ไม่ระงับข้อผิดพลาดอีกต่อไปเนื่องจากไม่ได้อยู่ในตำแหน่งหลักและ./tool add-commentsจะทำการระงับใหม่ในตำแหน่งที่ไม่ได้รับการสนับสนุน ./toolสคริปต์สามารถเข้าถึงได้โดยการโคลนที่เก็บกระแสบน GitHub
  • การปราบปรามโดยไม่มีรหัสข้อผิดพลาดจะยังคงระงับข้อผิดพลาดใด ๆ และทั้งหมดในตำแหน่งของพวกเขา แต่เมื่อเราเปิดตัวคุณลักษณะรหัสข้อผิดพลาดคุณสามารถเพิ่มรหัสที่เหมาะสมลงในโค้ดเบสของคุณผ่านกระบวนการที่คล้ายกันดังที่กล่าวมาข้างต้น การลบความคิดเห็นเก่าทั้งหมดของคุณและเพิ่มเข้าไปใหม่add-commentsจะรวมรหัสข้อผิดพลาดในความคิดเห็นที่เพิ่มเข้ามาใหม่