जावास्क्रिप्ट में विशिष्ट त्रुटियों को संभालना (विचार अपवाद)


112

आप विभिन्न प्रकार की त्रुटियों को कैसे लागू करेंगे, ताकि आप विशिष्ट लोगों को पकड़ सकें और दूसरों को बुलबुला बनने दें ..?

इसे प्राप्त करने का एक तरीका Errorवस्तु के प्रोटोटाइप को संशोधित करना है :

Error.prototype.sender = "";


function throwSpecificError()
{
    var e = new Error();

    e.sender = "specific";

    throw e;
}

विशिष्ट त्रुटि पकड़ें:

try
{
    throwSpecificError();
}

catch (e)
{
    if (e.sender !== "specific") throw e;

    // handle specific error
}


क्या आप लोगों को कोई विकल्प मिला है?

जवाबों:


159

कस्टम अपवाद बनाने के लिए, आप त्रुटि ऑब्जेक्ट से वारिस कर सकते हैं:

function SpecificError () {

}

SpecificError.prototype = new Error();

// ...
try {
  throw new SpecificError;
} catch (e) {
  if (e instanceof SpecificError) {
   // specific error
  } else {
    throw e; // let others bubble up
  }
}

त्रुटि से विरासत में मिले बिना एक न्यूनतर दृष्टिकोण, एक साधारण वस्तु को एक नाम और एक संदेश गुण फेंक सकता है:

function throwSpecificError() {
  throw {
    name: 'SpecificError',
    message: 'SpecificError occurred!'
  };
}


// ...
try {
  throwSpecificError();
} catch (e) {
  if (e.name == 'SpecificError') {
   // specific error
  } else {
    throw e; // let others bubble up
  }
}

2
इनहेरिट करने से Errorसमस्याएं होती हैं। देखें stackoverflow.com/questions/1382107/...
क्रीसेंट ताजा

5
इस कोड के साथ समस्या: } catch (e) { if (e.name == 'SpecificError') { // specific error } else { throw e; // let others bubble up } }यह IE7 में काम नहीं करेगा, "अपवाद फेंक दिया और पकड़ा नहीं" त्रुटि। एमएसडीएन से अत्यधिक मूर्खतापूर्ण (हमेशा की तरह) स्पष्टीकरण निम्नलिखित है: "आपने एक फेंक स्टेटमेंट को शामिल किया था, लेकिन यह एक प्रयास ब्लॉक के भीतर संलग्न नहीं था, या त्रुटि को फंसाने के लिए कोई संबद्ध कैच ब्लॉक नहीं था। अपवाद को कोशिश के भीतर से फेंक दिया जाता है। थ्रो स्टेटमेंट का उपयोग कर, और कैच स्टेटमेंट के साथ ट्रायल ब्लॉक के बाहर पकड़ा गया। "
यूजीन कुजमेनको

1
वैसे Microsoft का C # निश्चित रूप से जावास्क्रिप्ट से बेहतर त्रुटियों को हैंडल करता है: P। Mozzilla ने फ़ायरफ़ॉक्स के साथ कुछ ऐसा जोड़ा है जो ऐसा है। हालांकि यह एक्मास्क्रिप्ट मानक में नहीं है, यहां तक ​​कि ईएस 6 भी नहीं है, लेकिन वे यह भी समझाते हैं कि इसे कैसे अनुरूप बनाना है, हालांकि यह उतना उपयुक्त नहीं है। मूल रूप से ऊपर के समान, लेकिन उपयोग करना instanceOf। चेक यहाँ
बार्ट

जावास्क्रिप्ट में आप जो चाहें फेंक सकते हैं, यह एक साधारण स्ट्रिंग हो, एक संख्या (थिंक त्रुटि कोड) या पूरी तरह से योग्य वस्तु हो। मिठाई!
अब्राहम ब्रुक्स

1
@ लिसननेल, यदि आप मेरे कोड उदाहरण को ध्यान से देखते हैं, तो आप देखेंगे कि मैं nameकंस्ट्रक्टर फ़ंक्शन की संपत्ति का उपयोग करने का सुझाव नहीं दे रहा था । मैं एक nameसंपत्ति के साथ एक कस्टम मेड वस्तु को फेंकने का सुझाव दे रहा था , जो टूट नहीं जाएगा ...
सीएमएस

15

जैसा कि नीचे टिप्पणी में उल्लेख किया गया है कि यह मोज़िला विशिष्ट है, लेकिन आप 'सशर्त पकड़' ब्लॉक का उपयोग कर सकते हैं। उदाहरण के लिए:

try {
  ...
  throwSpecificError();
  ...
}
catch (e if e.sender === "specific") {
  specificHandler(e);
}
catch (e if e.sender === "unspecific") {
  unspecificHandler(e);
}
catch (e) {
  // don't know what to do
  throw e;
} 

यह जावा में उपयोग किए गए टाइप किए गए अपवाद से निपटने के लिए कुछ और अधिक देता है, कम से कम वाक्यात्मक रूप से।


सीएमएस के उत्तर के साथ गठबंधन करें और यह एकदम सही है।
एटल गोराल

3
सशर्त पकड़ कुछ ऐसा है जिसे मैं या तो पहले नहीं जानता था या फिर भूल गया था। मुझे शिक्षित / याद दिलाने के लिए धन्यवाद! +1
एट्स गोरल

12
केवल फ़ायरफ़ॉक्स (2.0 के बाद से) द्वारा समर्थित है। यह अन्य ब्राउज़रों में पार्स भी नहीं करता है; आपको केवल सिंटैक्स त्रुटियां मिलती हैं।
वर्धमान ताजा

10
हाँ, यह एक मोज़िला-मात्र विस्तार है, यह मानकीकरण के लिए भी प्रस्तावित नहीं है। सिंटेक्स-स्तरीय विशेषता होने के कारण इसके लिए सूँघने का कोई तरीका नहीं है और वैकल्पिक रूप से इसका उपयोग किया जाता है।
बॉब

3
इसके अतिरिक्त, प्रस्तावित समाधान के गैर-मानक होने के संबंध में। उद्धरण फार्म [मोज़िला जावास्क्रिप्ट संदर्भ [( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... ):This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.
informatik01

10

try-catch-finally.js

Try-catch-आखिरकार। Js का उपयोग करके , आप _tryफ़ंक्शन को एक अनाम कॉलबैक के साथ कॉल कर सकते हैं , जिसे वह कॉल करेगा, और आप .catchविशिष्ट त्रुटियों को पकड़ने के लिए कॉल कॉल कर सकते हैं, और किसी .finallyभी तरह से निष्पादित करने के लिए कॉल कर सकते हैं।

उदाहरण

_try(function () {
    throw 'My error';
})
.catch(Error, function (e) {
    console.log('Caught Error: ' + e);
})
.catch(String, function (e) {
    console.log('Caught String: ' + e);
})
.catch(function (e) {
    console.log('Caught other: ' + e);
})
.finally(function () {
    console.log('Error was caught explicitly');
});

आधुनिक तीर फ़ंक्शंस और टेम्पलेट शाब्दिक के साथ उदाहरण

_try(() => {
  throw 'My error';
}).catch(Error, e => {
  console.log(`Caught Error: ${e}`);
}).catch(String, e => {
  console.log(`Caught String: ${e}`);
}).catch(e => {
  console.log(`Caught other: ${e}`);
}).finally(() => {
  console.log('Error was caught explicitly');
});

2

निर्यात उपयोग के लिए मॉड्यूल

/**
 * Custom InputError
 */
class InputError extends Error {
  /**
   * Create InputError
   * @param {String} message
   */
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

/**
 * Custom AuthError
 */
class AuthError extends Error {
  /**
   * Create AuthError
   * @param {String} message
   */
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

/**
 * Custom NotFoundError
 */
class NotFoundError extends Error {
  /**
   * Create NotFoundError
   * @param {String} message
   */
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = {
  InputError: InputError,
  AuthError: AuthError,
  NotFoundError: NotFoundError
};

स्क्रिप्ट में आयात करें:

const {InputError, AuthError, NotFoundError} = require(path.join(process.cwd(), 'lib', 'errors'));

उपयोग:

function doTheCheck = () =>
  checkInputData().then(() => {
    return Promise.resolve();
  }).catch(err => {
    return Promise.reject(new InputError(err));
  });
};

कॉलिंग कोड बाहरी:

doTheCheck.then(() => {
  res.send('Ok');
}).catch(err => {
  if (err instanceof NotFoundError) {
    res.status(404).send('Not found');
  } else if (err instanceof AuthError) {
    res.status(301).send('Not allowed');
  } else if (err instanceof InputError) {
    res.status(400).send('Input invalid');
  } else {
    console.error(err.toString());
    res.status(500).send('Server error');
  }
});

0

मुझे इनमें से कोई भी समाधान पसंद नहीं था इसलिए मैंने अपना बनाया। ट्राइ-कैच-आखिर। Js इसके अलावा बहुत अच्छा है कि अगर आप कोशिश करने से पहले एक छोटे अंडरस्कोर (_) को भूल जाते हैं तो कोड अभी भी सिर्फ ठीक चलेगा, लेकिन कुछ भी नहीं पकड़ा जाएगा! छी।

CatchFilter

मैंने अपने कोड में एक CatchFilter जोड़ा:

"use strict";

/**
 * This catches a specific error. If the error doesn't match the errorType class passed in, it is rethrown for a
 * different catch handler to handle.
 * @param errorType The class that should be caught
 * @param funcToCall The function to call if an error is thrown of this type
 * @return {Function} A function that can be given directly to the `.catch()` part of a promise.
 */
module.exports.catchOnly = function(errorType, funcToCall) {
  return (error) => {
    if(error instanceof errorType) {
      return funcToCall(error);
    } else {
      // Oops, it's not for us.
      throw error;
    }
  };
};

अब मैं छान सकता हूं

अब मैं C # या Java में फ़िल्टर कर सकता हूं:

new Promise((resolve, reject => {
   <snip><snip>
}).catch(CatchFilter.catchOnly(MyError, err =>
   console.log("This is for my error");
}).catch(err => {
   console.log("This is for all of the other errors.");
});

-2
    <li>
      <span>onWarning:</span>
      <span id="msg_warning"></span>
    </li>

  try {
  // load face detection model
  await changeFaceDetector(MTCNN)
  changeInputSize(128)

  // try to access users webcam and stream the images
  // to the video element

    const stream = await navigator.mediaDevices.getUserMedia({ video: {} })
    const videoEl = $('#inputVideo').get(0)
    videoEl.srcObject = stream
  }
  catch(err) {
    //$("#msg_error").html(`Requested device not found`);
    $("#msg_error").html(err.message);
    console.log(err.message);
  }

नमस्ते, StackOverflow में आपका स्वागत है। पहले से पोस्ट किए गए अन्य 5 उत्तरों से आपका उत्तर बेहतर / अधिक कुशल / आदि कैसे है?
मज़ारेज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.