ฉันจะดึงข้อมูลทั้งหมดของข้อยกเว้นดั้งเดิมของ JavaScript ได้อย่างไร

เนื่องจาก JavaScript ดำเนินการในฝั่งไคลเอ็นต์ ฉันไม่สามารถควบคุมตัวแปรสภาพแวดล้อมจำนวนมากได้ และในบางครั้ง แอปของฉันอาจจะส่งข้อยกเว้น

สิ่งที่ฉันต้องการทำคือการได้รับข้อยกเว้นนี้และทำให้แอปของฉันล้มเหลวอย่างสวยงาม และแสดงข้อมูลสูงสุดเท่าที่เป็นไปได้ให้กับผู้ใช้ปลายทาง (ผู้ใช้ปลายทางของฉันเป็นผู้ใช้ทางเทคนิค) แน่นอนว่าการจัดการข้อผิดพลาดสามารถทำได้ผ่านบล็อก try...catch แบบง่ายๆ

สิ่งที่ทำให้ฉันรำคาญคือ ฉันจะรู้ได้อย่างไรว่าข้อมูลใดถูกจัดเก็บไว้ในข้อยกเว้นดั้งเดิมที่บล็อก catch จับได้

ฉันคิดว่าข้อยกเว้นดั้งเดิมที่เกิดขึ้นโดยเอ็นจิ้น JS ของเบราว์เซอร์นั้นเป็นเพียงอ็อบเจ็กต์จากคลาส Error โดยการรันโค้ดนี้:

try {
  a;
} catch (ex) {
  console.log(ex);
  console.log(new ReferenceError("`Custom` error"));
}

ฉันได้โครงสร้างเดียวกัน:

ReferenceError: a is not defined
    at http://stacksnippets.net/js:14:3
ReferenceError: `Custom` error
    at http://stacksnippets.net/js:17:15

console.log ของวัตถุปกติ เล็กน้อย แตกต่างไปจากนี้ แต่สมมติว่าตัวแปร ex เป็นวัตถุ ฉันสามารถวนซ้ำโดยใช้ for...in ใช่ไหม?

ไม่

รหัสนี้ไม่แสดงอะไรเลยในบันทึก:

try {
  a;
} catch (ex) {
  for (prop in ex) {
    console.log(prop, ": ", ex[prop]);
  }
}

ดังนั้น คำถามของฉันคือ: ฉันจะรับข้อมูลทั้งหมดที่จัดเก็บไว้ในข้อยกเว้น JavaScript ดั้งเดิมได้อย่างไร

ใช่ ฉันรู้ว่าฉันสามารถเข้าถึงคุณสมบัติได้โดยตรงโดย ex.name, ex.description, ex.message, ex.stack และอื่นๆ แต่ฉันต้องการหลีกเลี่ยงสิ่งนั้น เบราว์เซอร์บางตัวสามารถใช้งานบางอย่างที่เบราว์เซอร์อื่นไม่มี ดังนั้นฉันจะพลาดข้อมูลบางอย่างเมื่อทำงานในเบราว์เซอร์แรก (ดังที่คุณเห็นโดย คำถามนี้ เช่น คุณสมบัติ stack ถูกนำมาใช้ครั้งแรกโดย Firefox)

และหากมีใครสามารถอธิบายได้ ฉันอยากจะเข้าใจว่าธรรมชาติที่แท้จริงของข้อยกเว้น JavaScript คืออะไร (พวกมันเป็นวัตถุหรือไม่ ทำไมมันจึงดูแตกต่างออกไปในคอนโซล?) และทำไมฉันไม่สามารถวนซ้ำแม้ว่ามันจะมี for.. .in block (อาจเป็นคำตอบที่เกี่ยวข้องกันมาก)

ขอบคุณ.


person Dinei    schedule 17.06.2015    source แหล่งที่มา


คำตอบ (1)


ฉันต้องการทำความเข้าใจว่าธรรมชาติที่แท้จริงของข้อยกเว้น JavaScript คืออะไร (เป็นวัตถุหรือไม่ เพราะเหตุใดจึงดูแตกต่างกันมากในคอนโซล)

ข้อยกเว้น Javascript คือวัตถุ Javascript ปกติ คุณสามารถดูคำจำกัดความของออบเจ็กต์ได้ที่นี่

และเหตุใดฉันจึงไม่สามารถวนซ้ำด้วยบล็อก for...in ได้ (อาจเป็นคำตอบที่เกี่ยวข้องกันมาก)

การวนซ้ำคุณสมบัติของข้อผิดพลาดโดยใช้ for (prop in ex) { ไม่ทำงานเนื่องจากคุณสมบัติไม่ได้ถูกทำเครื่องหมายเป็น นับได้ (นี่คือ ยังแสดงอยู่ในข้อมูลโค้ดด้านล่างด้วยการพิมพ์คำอธิบายคุณสมบัติ)

คุณสามารถเปลี่ยนไปใช้ getOwnPropertyNames ได้ เพื่อแสดงรายการคุณสมบัติทั้งหมด

โค้ดด้านล่างแสดงให้เห็นว่าสามารถใช้งานได้อย่างไร - ไม่แน่ใจว่าจะใช้ getOwnPropertyNames & ex[property] ในลักษณะนี้ได้หรือไม่ แต่ก็เป็นวิธีแก้ปัญหาที่เป็นไปได้

function propsToStr(obj) {
  var str = '';
  for (prop in obj) {
    str += prop + "=" + obj[prop] + ",";
  }
  return str;
}

try {
  a;
} catch (ex) {
  console.log(ex);
  var propertyNames = Object.getOwnPropertyNames(ex);
  propertyNames.forEach(function(property) {
    var descriptor = Object.getOwnPropertyDescriptor(ex, property);
    console.log(property + ":" + ex[property] + ":" + propsToStr(descriptor));
  });
}

person 6ton    schedule 17.06.2015