PHP: अपवाद बनाम त्रुटियाँ?


116

शायद मैं इसे PHP मैनुअल में कहीं याद कर रहा हूं, लेकिन वास्तव में एक त्रुटि और एक अपवाद के बीच अंतर क्या है? एकमात्र अंतर जो मैं देख सकता हूं वह यह है कि त्रुटियों और अपवादों को अलग-अलग तरीके से नियंत्रित किया जाता है। लेकिन क्या एक अपवाद का कारण बनता है और क्या एक त्रुटि का कारण बनता है?

जवाबों:


87

अपवाद फेंक दिए जाते हैं - उन्हें पकड़े जाने का इरादा है। त्रुटियां आमतौर पर अप्राप्य हैं। उदाहरण के लिए कहते हैं - आपके पास कोड का एक ब्लॉक है जो एक डेटाबेस में एक पंक्ति सम्मिलित करेगा। यह संभव है कि यह कॉल विफल हो (डुप्लिकेट आईडी) - आप एक "त्रुटि" चाहते हैं जो इस मामले में एक "अपवाद" है। जब आप इन पंक्तियों को सम्मिलित कर रहे हैं, तो आप ऐसा कुछ कर सकते हैं

try {
  $row->insert();
  $inserted = true;
} catch (Exception $e) {
  echo "There was an error inserting the row - ".$e->getMessage();
  $inserted = false;
}

echo "Some more stuff";

कार्यक्रम निष्पादन जारी रहेगा - क्योंकि आपने अपवाद को 'पकड़' लिया है। जब तक इसे पकड़ा नहीं जाता है, तब एक अपवाद को एक त्रुटि माना जाएगा। यह आपको फेल होने के बाद भी प्रोग्राम का निष्पादन जारी रखने की अनुमति देगा।


29
Errors are generally unrecoverable<- वास्तव में, यह वास्तव में सच नहीं है। E_ERRORऔर E_PARSEदो सबसे आम अपरिवर्तनीय त्रुटियां हैं (कुछ अन्य हैं) लेकिन देव में आपको देखने वाली अधिकांश त्रुटियां पुनर्प्राप्त करने योग्य हैं ( E_NOTICE, E_WARNINGएट अल)। दुर्भाग्य से PHP की त्रुटि हैंडलिंग एक पूर्ण गड़बड़ है - सभी प्रकार की चीजें त्रुटियों को ट्रिगर करती हैं (उदाहरण के लिए, फ़ाइल सिस्टम फ़ंक्शन का विशाल बहुमत)। सामान्य अपवादों में "OOP तरीका" होता है, लेकिन दुर्भाग्य से PHP के कुछ मूल OOP API अपवादों के बजाय त्रुटियों का उपयोग करते हैं :-(
डेवग्रैंडमैन

1
@DaveRandom E_NOTICE, E_WARNING परिभाषा के अनुसार "त्रुटियां" नहीं हैं? मैंने हमेशा उन्हें प्रोग्रामर को सूचित करने के लिए 'संदेश' PHP प्रदर्शित करता है कि कोड s / उन्होंने लिखा है कि कुछ गलत हो सकता है।
slhsen

2
@ इस मुद्दे को वास्तव में भद्दा शब्दावली है, इन संदेशों के सभी रूप PHP में "त्रुटि हैंडलिंग प्रणाली" के माध्यम से जाते हैं, शब्दार्थ ये सभी घटनाएं "त्रुटियां" हैं, भले ही शब्दार्थ सूचना / चेतावनी सबसे निश्चित रूप से एक समान नहीं है " त्रुटि "उस संदर्भ में। शुक्र है कि आगामी PHP7 ने कम से कम इन चीजों को सबसे ज्यादा चीजों को बदलने योग्य अपवादों (एक नए Throwableइंटरफ़ेस के माध्यम से ) में बदलकर इस गड़बड़ को सुलझाने का मार्ग प्रशस्त किया है , दोनों को वास्तविक रूप से अलग और सही तरीके से व्यक्त करने के लिए बहुत अधिक अभिव्यंजक और निरपेक्ष तरीका दिया है। समस्याओं और सलाहकार संदेश
डेवग्रैंडैमएक्स

"कार्यक्रम निष्पादन जारी रहेगा" क्या मैंने मान लिया है? चूंकि PHP कहता है "जब एक अपवाद को फेंक दिया जाता है, तो कथन के बाद कोड निष्पादित नहीं किया जाएगा" ( php.net/manual/en/language.exception.php )
रॉबर्ट सिनक्लेयर

1
मुझे लगता है कि ओपी का मतलब Errorवीएस के वंशजों के बीच अंतर के बारे में अधिक था Exception
XedinUnogn 14

55

मैं आम तौर set_error_handlerपर एक ऐसे फंक्शन में जाता हूं जो त्रुटि लेता है और एक अपवाद को फेंक देता है ताकि जो कुछ भी हो, उससे निपटने के लिए मेरे पास केवल अपवाद होंगे। कोई और अधिक @file_get_contentsअच्छा और साफ कोशिश / पकड़।

डिबग स्थितियों में मेरे पास एक अपवाद हैंडलर भी है जो पृष्ठ की तरह एक asp.net आउटपुट देता है। मैं इसे सड़क पर पोस्ट कर रहा हूं लेकिन अगर अनुरोध किया जाए तो मैं बाद में उदाहरण स्रोत पोस्ट करूंगा।

संपादित करें:

जैसा कि वादा किया गया था, मैंने एक नमूना बनाने के लिए अपने कुछ कोड काटे और चिपकाए। मैंने अपने कार्य केंद्र पर फ़ाइल करने के लिए नीचे को सहेजा है, आप NO LONGER परिणाम यहाँ देख सकते हैं (क्योंकि लिंक टूट गया है)।

<?php

define( 'DEBUG', true );

class ErrorOrWarningException extends Exception
{
    protected $_Context = null;
    public function getContext()
    {
        return $this->_Context;
    }
    public function setContext( $value )
    {
        $this->_Context = $value;
    }

    public function __construct( $code, $message, $file, $line, $context )
    {
        parent::__construct( $message, $code );

        $this->file = $file;
        $this->line = $line;
        $this->setContext( $context );
    }
}

/**
 * Inspire to write perfect code. everything is an exception, even minor warnings.
 **/
function error_to_exception( $code, $message, $file, $line, $context )
{
    throw new ErrorOrWarningException( $code, $message, $file, $line, $context );
}
set_error_handler( 'error_to_exception' );

function global_exception_handler( $ex )
{
    ob_start();
    dump_exception( $ex );
    $dump = ob_get_clean();
    // send email of dump to administrator?...

    // if we are in debug mode we are allowed to dump exceptions to the browser.
    if ( defined( 'DEBUG' ) && DEBUG == true )
    {
        echo $dump;
    }
    else // if we are in production we give our visitor a nice message without all the details.
    {
        echo file_get_contents( 'static/errors/fatalexception.html' );
    }
    exit;
}

function dump_exception( Exception $ex )
{
    $file = $ex->getFile();
    $line = $ex->getLine();

    if ( file_exists( $file ) )
    {
        $lines = file( $file );
    }

?><html>
    <head>
        <title><?= $ex->getMessage(); ?></title>
        <style type="text/css">
            body {
                width : 800px;
                margin : auto;
            }

            ul.code {
                border : inset 1px;
            }
            ul.code li {
                white-space: pre ;
                list-style-type : none;
                font-family : monospace;
            }
            ul.code li.line {
                color : red;
            }

            table.trace {
                width : 100%;
                border-collapse : collapse;
                border : solid 1px black;
            }
            table.thead tr {
                background : rgb(240,240,240);
            }
            table.trace tr.odd {
                background : white;
            }
            table.trace tr.even {
                background : rgb(250,250,250);
            }
            table.trace td {
                padding : 2px 4px 2px 4px;
            }
        </style>
    </head>
    <body>
        <h1>Uncaught <?= get_class( $ex ); ?></h1>
        <h2><?= $ex->getMessage(); ?></h2>
        <p>
            An uncaught <?= get_class( $ex ); ?> was thrown on line <?= $line; ?> of file <?= basename( $file ); ?> that prevented further execution of this request.
        </p>
        <h2>Where it happened:</h2>
        <? if ( isset($lines) ) : ?>
        <code><?= $file; ?></code>
        <ul class="code">
            <? for( $i = $line - 3; $i < $line + 3; $i ++ ) : ?>
                <? if ( $i > 0 && $i < count( $lines ) ) : ?>
                    <? if ( $i == $line-1 ) : ?>
                        <li class="line"><?= str_replace( "\n", "", $lines[$i] ); ?></li>
                    <? else : ?>
                        <li><?= str_replace( "\n", "", $lines[$i] ); ?></li>
                    <? endif; ?>
                <? endif; ?>
            <? endfor; ?>
        </ul>
        <? endif; ?>

        <? if ( is_array( $ex->getTrace() ) ) : ?>
        <h2>Stack trace:</h2>
            <table class="trace">
                <thead>
                    <tr>
                        <td>File</td>
                        <td>Line</td>
                        <td>Class</td>
                        <td>Function</td>
                        <td>Arguments</td>
                    </tr>
                </thead>
                <tbody>
                <? foreach ( $ex->getTrace() as $i => $trace ) : ?>
                    <tr class="<?= $i % 2 == 0 ? 'even' : 'odd'; ?>">
                        <td><?= isset($trace[ 'file' ]) ? basename($trace[ 'file' ]) : ''; ?></td>
                        <td><?= isset($trace[ 'line' ]) ? $trace[ 'line' ] : ''; ?></td>
                        <td><?= isset($trace[ 'class' ]) ? $trace[ 'class' ] : ''; ?></td>
                        <td><?= isset($trace[ 'function' ]) ? $trace[ 'function' ] : ''; ?></td>
                        <td>
                            <? if( isset($trace[ 'args' ]) ) : ?>
                                <? foreach ( $trace[ 'args' ] as $i => $arg ) : ?>
                                    <span title="<?= var_export( $arg, true ); ?>"><?= gettype( $arg ); ?></span>
                                    <?= $i < count( $trace['args'] ) -1 ? ',' : ''; ?> 
                                <? endforeach; ?>
                            <? else : ?>
                            NULL
                            <? endif; ?>
                        </td>
                    </tr>
                <? endforeach;?>
                </tbody>
            </table>
        <? else : ?>
            <pre><?= $ex->getTraceAsString(); ?></pre>
        <? endif; ?>
    </body>
</html><? // back in php
}
set_exception_handler( 'global_exception_handler' );

class X
{
    function __construct()
    {
        trigger_error( 'Whoops!', E_USER_NOTICE );      
    }
}

$x = new X();

throw new Exception( 'Execution will never get here' );

?>

वह मददगार होगा। PHP से निपटने के लिए मेरे द्वारा किए गए समय को कम करने के लिए कुछ भी मदद करेगा। :-)
जेसन बेकर

अच्छा कोड, धन्यवाद। मुझे नहीं मिलता कि दसवीं कक्षा कहाँ से आती है, और इसका उद्देश्य क्या है?
एलेक

"set_exception_handler ('Global_exception_handler') के नीचे सब कुछ;" बस डेमो है, आपको इसकी आवश्यकता नहीं होगी, यह केवल यह दिखाने के लिए है कि सामान्य रूप से गैर-अपवाद त्रुटि स्थिति में क्या होगा।
क्रिश

मानक PHP विशेष रूप से एक सामान्य त्रुटि हैंडलर से फेंके जाने के लिए ErrorException को परिभाषित करता है। क्या आप मुझे अपनी पोस्ट को संपादित करने और अपडेट करने की अनुमति देंगे?
टिबेरिउ-आयनो स्टेन

@ Tiberiu-IonuțStan: यकीन है, लेकिन काम कर रहे उदाहरण सिंक से बाहर हो जाएगा। इसके अलावा, आजकल मैं शायद लोगों को निजी- void.com के बजाय github.com/theredhead/red.web/blob/master/src/lib/bootstrap.php की ओर इंगित करूंगा ।
क्रिस

21

जवाब में कमरे में हाथी के बारे में बात करने लायक है

त्रुटियां रन-टाइम में त्रुटि स्थिति से निपटने का पुराना तरीका है। आमतौर पर कोड set_error_handlerकुछ कोड को निष्पादित करने से पहले कॉल को कुछ इस तरह बना देगा । असेंबली भाषा की परंपरा का पालन करना बाधित होता है। यहाँ कुछ बुनियादी कोड कैसे दिखेगा।

on error :divide_error

print 1/0
print "this won't print"

:divide_error

if errcode = X
   print "divide by zero error"

यह सुनिश्चित करना कठिन था कि set_error_handlerसही मूल्य के साथ बुलाया जाएगा। और इससे भी बदतर, एक अलग प्रक्रिया के लिए एक कॉल किया जा सकता है जो त्रुटि हैंडलर को बदल देगा। साथ ही कई बार set_error_handlerकॉल और हैंडलर से कॉल को इंटरसेप्ट किया गया । कोड को तुरंत नियंत्रण से बाहर करना आसान था। अपवाद कोडिंग सिंटैक्स और औपचारिक अर्थों को औपचारिक रूप से समझाते हुए बचाव में आया कि अच्छा कोड वास्तव में क्या कर रहा था।

try {
   print 1/0;
   print "this won't print";
} catch (DivideByZeroException $e) {
   print "divide by zero error";
}

कोई अलग फ़ंक्शन या गलत त्रुटि हैंडलर को कॉल करने का जोखिम नहीं। कोड अब उसी स्थान पर होने की गारंटी है। साथ ही हमें बेहतर त्रुटि संदेश मिलते हैं।

PHP का उपयोग केवल त्रुटि से निपटने के लिए किया जाता था, जब कई अन्य भाषाएँ पहले से ही अधिमान्य अपवाद हैंडलिंग मॉडल के लिए विकसित हुई थीं। अंततः PHP के निर्माताओं ने अपवाद संचालन को लागू किया। लेकिन पुराने कोड का समर्थन करने की संभावना है, उन्होंने त्रुटि से निपटने को रखा और अपवाद हैंडलिंग की तरह त्रुटि से निपटने का तरीका प्रदान किया। इसके अलावा, इस बात की कोई गारंटी नहीं है कि कुछ कोड त्रुटि हैंडलर को रीसेट नहीं कर सकते हैं जो कि ठीक वही था जो अपवाद हैंडलिंग प्रदान करने के लिए था।

अंतिम जवाब

अपवाद हैंडलिंग से पहले जिन त्रुटियों को कोड किया गया था, संभावना है कि अभी भी त्रुटियां हैं। नई त्रुटियों की संभावना अपवाद हैं। लेकिन इसमें कोई डिज़ाइन या तर्क नहीं है कि कौन सी त्रुटियां हैं और कौन से अपवाद हैं। यह सिर्फ उस समय पर आधारित था जो उस समय उपलब्ध था जिसे कोडित किया गया था, और प्रोग्रामर की वरीयता इसे कोडित करना था।


3
यह वास्तविक कारण है कि अपवाद और त्रुटियां सह-अस्तित्व क्यों हैं। यदि खरोंच से डिज़ाइन किया गया है, तो php में केवल एक या दूसरे को शामिल करना चाहिए।
टॉमस जुबीरी

1
यह मेरी राय में सबसे अच्छा जवाब है, क्योंकि यह सबसे विस्तृत और व्याख्यात्मक है।
रॉबर्ट कुज़्नियर

8

यहाँ जोड़ने वाली एक बात अपवादों और त्रुटियों को संभालने के बारे में है। एप्लिकेशन डेवलपर के उद्देश्य के लिए, दोनों त्रुटियां और अपवाद "खराब चीजें" हैं, जिन्हें आप उन समस्याओं के बारे में जानने के लिए रिकॉर्ड करना चाहते हैं जो आपके आवेदन में हैं - ताकि आपके ग्राहकों को लंबे समय में बेहतर अनुभव हो।

तो यह एक त्रुटि हैंडलर लिखने के लिए समझ में आता है कि आप अपवादों के लिए क्या करते हैं।


लिंक प्रदान करने के लिए धन्यवाद!
माइक मूर

@ एलेक्स वेन्स्टीन: लिंक टूट गया है
मार्को डेमायो

7

जैसा कि अन्य उत्तरों में कहा गया है, PHP में त्रुटियों को संभालने के लिए अपवाद हैंडलर को त्रुटि हैंडलर सेट करना सबसे अच्छा तरीका है। मैं थोड़ा सरल सेटअप का उपयोग करता हूं:

set_error_handler(function ($errno, $errstr, $errfile, $errline ) {
        if (error_reporting()) {
                throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
        }
});

कृपया ऑपरेटर को काम error_reporting()करते रहने के लिए चेक पर ध्यान दें @। इसके अलावा, कस्टम अपवाद को परिभाषित करने की आवश्यकता नहीं है, PHP के लिए एक अच्छा वर्ग है।

अपवादों को फेंकने का बड़ा लाभ यह है कि अपवाद में उनके साथ जुड़े स्टैक ट्रेस होते हैं, इसलिए यह पता लगाना आसान है कि समस्या कहां है।


5

पुन: "लेकिन क्या वास्तव में एक त्रुटि और एक अपवाद के बीच अंतर है?"

यहाँ मतभेदों के बारे में बहुत अच्छे उत्तर हैं। मैं अभी कुछ ऐसा जोड़ूंगा जिसमें अभी तक बात नहीं हुई है - प्रदर्शन। विशेष रूप से, यह अपवादों को फेंकने / संभालने और रिटर्न कोड को संभालने (या तो सफलता या कुछ त्रुटि) के बीच अंतर के लिए है। आमतौर पर, php में, इसका अर्थ होता है लौटने का falseया null, लेकिन वे अधिक विस्तृत हो सकते हैं जैसे फ़ाइल अपलोडिंग के साथ: http://php.net/manual/en/features.file-upload.errors.php आप एक अपवाद वस्तु भी वापस कर सकते हैं !

मैंने विभिन्न भाषाओं / प्रणालियों में कुछ प्रदर्शन किए हैं। आम तौर पर, त्रुटि वापसी कोड की जाँच की तुलना में अपवाद हैंडलिंग लगभग 10,000x धीमी है।

तो, अगर यह पूरी तरह से, सकारात्मक रूप से भी शुरू करने से पहले इसे खत्म करने की आवश्यकता है - ठीक है, तो आप भाग्य से बाहर हैं क्योंकि समय यात्रा मौजूद नहीं है। समय यात्रा के बिना, रिटर्न कोड सबसे तेज़ विकल्प उपलब्ध हैं।

संपादित करें:

अपवाद हैंडलिंग के लिए PHP अत्यधिक अनुकूलित है। वास्तविक विश्व परीक्षण से पता चलता है कि एक अपवाद को फेंकना केवल मूल्य वापस करने की तुलना में 2-10x धीमा है।


3
निश्चित रूप से, लेकिन अपवादों को फेंकने के लिए खोई गई साइकिल की मात्रा अतिरिक्त विवरणात्मक शक्तियों के लिए बनाई गई तुलना में अधिक है जो आपको अपवादों के साथ मिलती हैं। आप विशिष्ट प्रकार के अपवादों को फेंक सकते हैं, यहां तक ​​कि त्रुटि कोड को शामिल करने के लिए डेटा को अपवाद में भी जोड़ सकते हैं। मैं गंभीरता से आपके 10,000 * के दावे पर भी संदेह करता हूं। यहां तक ​​कि अगर आप समय के अंतर के बारे में सही हैं, तो रिटर्न करने में खर्च होने वाला समय और यदि नई परीक्षा, फेंक, किसी भी वास्तविक दुनिया के परिदृश्य में पकड़, तो निष्पादित कोड की तुलना में इतनी कम संभावना है कि यह निश्चित रूप से समय से पहले का अनुकूलन है। अपवादों को फेंको, वे समय के 90% से निपटने के लिए अच्छे हैं।
गर्नफ 21

1
1. 10,000x सटीक है - भाषा और संकलक विकल्पों के आधार पर कुछ विचरण के साथ। 2. आपको अशक्त / गलत नहीं लौटना है। आप एक नंबर - अधिकतम MAX_ULONG रिटर्न कोड वहीं वापस कर सकते हैं। आप वैकल्पिक रूप से एक असफल स्ट्रिंग लौटा सकते हैं और बस एक सफलता स्ट्रिंग या इंट या नल की जांच कर सकते हैं। 3. वास्तविक दुनिया के परिदृश्यों में हर घड़ी चक्र मायने रखता है। फेसबुक पर रोजाना 552 मिलियन एक्टिव यूजर्स हैं। मान लें कि अपवाद केवल 2x हैं और उपयोगकर्ता / पास चेकिंग .001s का मतलब है कि हर दिन प्रसंस्करण समय के 153 घंटे की बचत होती है। 10,000x पर यह 175 साल बचाता है। बस लॉगिन प्रयासों की जाँच करने के लिए - प्रत्येक दिन।
इवान

@ इवन: FYI, यहाँ उन्होंने अपवादों के साथ कोड का परीक्षण किया और यह धीमा नहीं लगता: stackoverflow.com/a/445094/260080
Marco Demaio

@MarcoDemaio यह सवाल बिना किसी अपवाद के केवल कोशिश / कैच ब्लॉक को कवर करता है। एक बेहतर परीक्षा होगी कि वे नोइसेप्ट () में एक मूल्य लौटाएँ और एक अपवाद को छोड़ दें ()। इसके अलावा, यह कई कार्यों के माध्यम से बुलबुला होना चाहिए। stackoverflow.com/a/104375/505172 बताता है कि PHP में अंतर वास्तव में 54x है। मैंने वास्तविक समय को देखते हुए अपना परीक्षण चलाया और यह 2-10x धीमा प्रतीत होता है। यह सभी तरह से उम्मीद से बेहतर है।
ईवान १

@ इवान: मैं तब चिंतित नहीं होता, मैं केवल अप्रत्याशित / अपरिवर्तनीय त्रुटियों को ट्रैक करने के लिए अपवादों का उपयोग करता हूं, भले ही यह 100 बार धीमा हो, मुझे परवाह नहीं होगी। मेरी चिंता बस कोशिश / ब्लॉक को जोड़कर कोड को धीमा बनाने के बारे में थी।
मार्को डेमायो

4

मुझे लगता है कि आप जिस awser को ढूंढ रहे हैं, वह है;

त्रुटियां आपके द्वारा उपयोग किए जाने वाले मानक सामान हैं, जैसे कि एक $ चर की गूंज है जो मौजूद नहीं है।
अपवाद केवल PHP 5 से ही हैं और वस्तुओं के साथ काम करते समय आते हैं।

इसे सरल रखने के लिए:

अपवाद वे त्रुटियां हैं जो आपको वस्तुओं से निपटने के दौरान मिलती हैं। कोशिश / कैच स्टेटमेंट आपको उनके बारे में कुछ करने देता है, हालाँकि और बहुत कुछ इफ़ेक्ट / स्टेटमेंट की तरह इस्तेमाल होता है। ऐसा करने की कोशिश करें, यदि समस्या है, तो कोई बात नहीं, यह करें।

यदि आप एक अपवाद को "पकड़" नहीं लेते हैं, तो यह एक मानक त्रुटि में बदल जाता है।

त्रुटियाँ php fundemental त्रुटियाँ हैं जो आमतौर पर आपकी स्क्रिप्ट को रोकती हैं।

कोशिश करें / पकड़ अक्सर PDO जैसे डेटाबेस कनेक्शन स्थापित करने के लिए उपयोग किया जाता है, जो कि यदि आप स्क्रिप्ट को पुनर्निर्देशित करना चाहते हैं या कुछ और करते हैं यदि कनेक्शन काम नहीं करता है। लेकिन यदि आप केवल त्रुटि संदेश प्रदर्शित करना चाहते हैं और स्क्रिप्ट को रोकना चाहते हैं, तो आपको इसकी आवश्यकता नहीं है, अनकहा अपवाद एक घातक त्रुटि में बदल जाता है। या आप एक साइट-वाइड एरर हैंडलिंग सेटिंग का भी उपयोग कर सकते हैं।

उम्मीद है की वो मदद करदे


3
अपवाद केवल PHP में प्रक्रियात्मक कोड के साथ उपयोग किया जा सकता है।
तिबेरिउ-आयनो स्टेन 16

2

PHP 7.1 और बाद में, एक कैच ब्लॉक पाइप (!) वर्ण का उपयोग करके कई अपवाद निर्दिष्ट कर सकता है। यह तब उपयोगी होता है जब विभिन्न श्रेणी के पदानुक्रमों के अलग-अलग अपवादों को एक समान किया जाता है।

try {
  // do something
} catch (Error | Exception $e) {
  echo $e->getMessage();
}

1

अपवादों को जानबूझकर एक फेंक, त्रुटियों का उपयोग करके कोड द्वारा फेंक दिया जाता है ... इतना नहीं।

किसी चीज के परिणामस्वरूप त्रुटियां आती हैं जो आमतौर पर नियंत्रित नहीं की जाती हैं। (IO त्रुटियाँ, TCP / IP त्रुटियाँ, अशक्त संदर्भ त्रुटियाँ)


1
आवश्यक रूप से यह सही नहीं है। कई मामलों में त्रुटियों की जाँच की जाती है और रिटर्न कोड जानबूझकर उचित रूप में वापस भेजे जाते हैं। वास्तव में, यह हर गैर-वस्तु उन्मुख भाषा के लिए मामला है। अपवाद केवल, साथ ही, नियम के अपवाद हैं। दोनों मामलों में, कुछ गलत हो जाता है, ध्यान दिया जाता है, और इसे संभालना चाहिए। PHP फ़ाइल अपलोड करना रिटर्न कोड के माध्यम से जानबूझकर त्रुटि से निपटने का एक उदाहरण है - php.net/manual/en/features.file-upload.errors.php
evan

1

मैं आपको त्रुटि नियंत्रण की सबसे असामान्य चर्चा देने का इरादा रखता हूं।

मैंने वर्षों पहले एक भाषा में एक बहुत अच्छा त्रुटि हैंडलर बनाया था, और हालांकि कुछ नाम बदल गए हैं, त्रुटि प्रसंस्करण के सिद्धांत आज भी समान हैं। मेरे पास एक कस्टम निर्मित मल्टी-टास्किंग ओएस था और सभी स्तरों पर डेटा त्रुटियों से पुनर्प्राप्त करने में सक्षम होना चाहिए, जिसमें कोई मेमोरी लीक, स्टैक विकास या क्रैश नहीं था। तो इस प्रकार मेरी समझ है कि त्रुटियों और अपवादों को कैसे संचालित किया जाना चाहिए और वे कैसे भिन्न होते हैं। मैं सिर्फ इतना कहूंगा कि मेरे पास इस बात की समझ नहीं है कि ट्राइ के कैच कैसे काम करते हैं, इसलिए मैं कुछ उपाय का अनुमान लगा रहा हूं।

त्रुटि प्रसंस्करण के लिए कवर के तहत होने वाली पहली चीज एक कार्यक्रम राज्य से दूसरे में कूद रही है। कैसे किया जाता है? मैं उस के लिए मिल जाएगा।

ऐतिहासिक रूप से, त्रुटियां पुरानी और सरल हैं, और अपवाद नए और थोड़े अधिक जटिल और सक्षम हैं। त्रुटियां तब तक ठीक काम करती हैं जब तक आपको उन्हें बुदबुदाने की जरूरत नहीं है, जो आपके पर्यवेक्षक को एक कठिन समस्या सौंपने के बराबर है।

त्रुटियां संख्याएं हो सकती हैं, जैसे त्रुटि संख्याएं, और कभी-कभी एक या अधिक संबद्ध स्ट्रिंग्स के साथ। उदाहरण के लिए यदि कोई फ़ाइल-पठन त्रुटि होती है, तो आप रिपोर्ट करने में सक्षम हो सकते हैं कि यह क्या है और संभवतः शालीनता से विफल है। (हे, यह पुराने दिनों की तरह बस दुर्घटनाग्रस्त होने से एक कदम है।)

अपवादों के बारे में अक्सर यह नहीं कहा जाता है कि अपवाद एक विशेष अपवाद स्टैक पर रखी गई वस्तुएं हैं। यह प्रोग्राम फ्लो के लिए एक रिटर्न स्टैक की तरह है, लेकिन यह त्रुटि की कोशिशों और कैच के लिए रिटर्न स्टेट है। (मैं उन्हें ePush और ePop कहता था, और? Abort एक सशर्त थ्रो था जो ePop होगा और उस स्तर तक पुनर्प्राप्त होगा, जबकि Abort एक पूर्ण मृत्यु या निकास था।)

स्टैक के निचले हिस्से पर शुरुआती कॉलर के बारे में जानकारी होती है, वह वस्तु जो राज्य के बारे में जानती है जब बाहरी कोशिश शुरू की गई थी, जो कि अक्सर तब होती है जब आपका कार्यक्रम शुरू किया गया था। शीर्ष पर, या स्टैक पर अगली परत, बच्चों के होने के साथ, और माता-पिता होने के नाते, अगली आंतरिक कोशिश / कैच ब्लॉक की अपवाद वस्तु है।

यदि आप एक कोशिश के अंदर एक कोशिश डालते हैं तो आप बाहरी कोशिश के शीर्ष पर आंतरिक कोशिश को रोक रहे हैं। जब आंतरिक प्रयास में कोई त्रुटि होती है और या तो आंतरिक पकड़ इसे संभाल नहीं सकती है या त्रुटि बाहरी प्रयास में फेंक दी जाती है, तो नियंत्रण बाहरी कैच ब्लॉक (ऑब्जेक्ट) में जाता है यह देखने के लिए कि क्या यह त्रुटि को संभाल सकता है, अर्थात आपके पर्यवेक्षक

तो यह त्रुटि स्टैक वास्तव में क्या करती है, प्रोग्राम फ्लो और सिस्टम स्थिति को चिह्नित करने और पुनर्स्थापित करने में सक्षम होने के लिए, दूसरे शब्दों में, यह किसी प्रोग्राम को रिटर्न स्टैक को क्रैश नहीं करने देता है और चीजों के गलत होने पर दूसरों (डेटा) को गड़बड़ कर देता है। इसलिए यह मेमोरी आवंटन पूल जैसे किसी भी अन्य संसाधन की स्थिति को भी बचाता है और इसलिए कैच होने पर यह उन्हें साफ कर सकता है। सामान्य तौर पर यह एक बहुत ही जटिल बात हो सकती है, और यही कारण है कि अपवाद हैंडलिंग अक्सर धीमी होती है। सामान्य तौर पर काफी हद तक इन अपवाद ब्लॉकों में जाने की जरूरत है।

तो एक कोशिश / पकड़ ब्लॉक सेट के एक राज्य के रूप में अगर अन्य सभी गड़बड़ हो जाता है पर लौटने में सक्षम हो। यह माता-पिता की तरह है। जब हमारा जीवन गड़बड़ हो जाता है तो हम अपने माता-पिता की गोद में वापस गिर सकते हैं और वे इसे फिर से सही कर देंगे।

आशा है कि मैंने आपको निराश नहीं किया।


1

आप इस टिप्पणी को जोड़ सकते हैं

function doSomething()
{
   /** @noinspection PhpUnhandledExceptionInspection */
   throw new Exception();
}

0

एक बार set_error_handler () परिभाषित हो गया है, त्रुटि हैंडलर अपवाद के समान है। नीचे देखें कोड:

 <?php
 function handleErrors( $e_code ) {
   echo "error code: " . $e_code . "<br>";
 }

 set_error_handler( "handleErrors" ); 

 trigger_error( "trigger a fatal error", E_USER_ERROR);
 echo "after error."; //it would run if set_error_handler is defined, otherwise, it wouldn't show
?>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.