Пример обработки ошибок: программа CustomErrors

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Приложение CustomErrors демонстрирует методы работы с пользовательскими ошибками при создании программы. Рассматриваются следующие техники:

  • Подтверждение пакета XML

  • Создание пользовательской ошибки

  • Генерация пользовательской ошибки

  • Уведомление пользователей о генерации ошибки

Получить файлы приложения для этого примера можно на странице www.adobe.com/go/learn_programmingAS3samples_flash_ru. Файлы приложения CustomErrors находятся в папке Samples/CustomError. Приложение состоит из следующих файлов.

File

Описание

CustomErrors.mxml

или

CustomErrors.fla

Основной файл приложения Flash (FLA) или Flex (MXML)

com/example/programmingas3/errors/ApplicationError.as

Класс, который служит базой для классов FatalError и WarningError.

com/example/programmingas3/errors/FatalError.as

Класс, который определяет ошибку FatalError, генерируемую приложением. Этот класс расширяет пользовательский класс ApplicationError.

com/example/programmingas3/errors/Validator.as

Класс, определяющий отдельный метод, который подтверждает поставляемый пользователем служебный пакет XML.

com/example/programmingas3/errors/WarningError.as

Класс, который определяет ошибку WarningError, генерируемую приложением. Этот класс расширяет пользовательский класс ApplicationError.

Рассмотрение приложения CustomErrors

При загрузке приложений Flex вызывается метод initApp(), а при загрузке приложений Flash Professional выполняется код временной шкалы (при отсутствии функций). Этот код определяет образец пакета XML, который необходимо проверить с помощью класса Validator. Выполняется следующий код:

employeeXML =  
    <employee id="12345"> 
        <firstName>John</firstName> 
        <lastName>Doe</lastName> 
        <costCenter>12345</costCenter> 
        <costCenter>67890</costCenter> 
    </employee>; 
}

Пакет XML позже отображается в экземпляре компонента TextArea в рабочей области. Это позволяет модифицировать пакет XML перед попыткой его повторного подтверждения.

При нажатии кнопки Validate (Подтвердить) вызывается метод validateData(). Этот метод проверяет служебный пакет XML (список служащих) с помощью метода validateEmployeeXML() класса Validator. Следующий код демонстрирует метод validateData():

function validateData():void 
{ 
    try 
    { 
        var tempXML:XML = XML(xmlText.text); 
        Validator.validateEmployeeXML(tempXML); 
        status.text = "The XML was successfully validated."; 
    } 
    catch (error:FatalError) 
    { 
        showFatalError(error); 
    } 
    catch (error:WarningError) 
    { 
        showWarningError(error); 
    } 
    catch (error:Error) 
    { 
        showGenericError(error); 
    } 
}

Прежде всего создается временный объект XML с помощью содержимого экземпляра компонента TextArea — xmlText. Затем вызывается метод validateEmployeeXML() в пользовательском классе Validator com.example.programmingas3/errors/Validator.as), который передает временный объект XML в качестве параметра. Если пакет XML оказывается действительным, экземпляр status компонента Label отображает подтверждающее сообщение и приложение закрывается. Если метод validateEmployeeXML() генерирует пользовательскую ошибку (то есть FatalError, WarningError или базовую ошибку Error), выполняется соответствующая инструкция catch , которая вызывает один из следующих методов: showFatalError(), showWarningError() или showGenericError(). Каждый из этих методов отображает в текстовой области с именем statusText соответствующее сообщение для уведомления пользователя о возникновении специфической ошибки. Каждый метод обновляет также экземпляр status компонента Label специальным сообщением.

Если при попытке подтверждения служебного пакета XML происходит фатальная ошибка, в текстовой области statusText отображается сообщение об ошибке, а экземпляр xmlText компонента TextArea и экземпляр validateBtn компонента Button отключаются, как показано в следующем коде:

function showFatalError(error:FatalError):void 
{ 
    var message:String = error.message + "\n\n"; 
    var title:String = error.getTitle(); 
    statusText.text = message + " " + title + "\n\nThis application has ended."; 
    this.xmlText.enabled = false; 
    this.validateBtn.enabled = false; 
    hideButtons(); 
}

Если вместо фатальной ошибки происходит предупреждающая ошибка, в текстовой области statusText также отображается сообщение об ошибке, но экземпляры компонентов TextArea (xmlText) и Button не отключаются. Метод showWarningError() отображает сообщение о пользовательской ошибке в текстовой области statusText. Также в сообщении пользователю предлагается сделать выбор: продолжить подтверждение XML или отменить выполнение сценария. Следующий фрагмент демонстрирует метод showWarningError():

function showWarningError(error:WarningError):void 
{ 
    var message:String = error.message + "\n\n" + "Do you want to exit this application?"; 
    showButtons(); 
    var title:String = error.getTitle(); 
    statusText.text = message; 
}

Метод closeHandler() вызывается при нажатии кнопок «Да» или «Нет». Следующий фрагмент демонстрирует метод closeHandler():

function closeHandler(event:CloseEvent):void 
{ 
    switch (event.detail) 
    { 
        case yesButton: 
            showFatalError(new FatalError(9999)); 
            break; 
        case noButton: 
            statusText.text = ""; 
            hideButtons(); 
            break; 
    } 
}

Если пользователь решает отменить выполнение сценария нажатием кнопки «Да», генерируется фатальная ошибка FatalError, что приводит к закрытию приложения.

Создание пользовательского валидатора

Пользовательский класс Validator содержит один метод validateEmployeeXML(). Метод validateEmployeeXML() использует один аргумент employee, который представляет собой проверяемый пакет XML. Метод validateEmployeeXML() имеет следующую структуру:

public static function validateEmployeeXML(employee:XML):void 
{ 
    // checks for the integrity of items in the XML 
    if (employee.costCenter.length() < 1) 
    { 
        throw new FatalError(9000); 
    } 
    if (employee.costCenter.length() > 1) 
    { 
        throw new WarningError(9001); 
    } 
    if (employee.ssn.length() != 1) 
    { 
        throw new FatalError(9002); 
    } 
}

Для утверждения служащий должен принадлежать к одному (и только одному) центру учета затрат. Если служащий не принадлежит ни к одному центру учета затрат, метод генерирует неустранимую ошибку FatalError, которая передается методу validateData() в главном файле приложения. Если служащий принадлежит к нескольким центрам учета затрат, генерируется предупреждающая ошибка WarningError. Окончательная проверка в валидаторе XML приводит к тому, что пользователь получает только один номер социального страхования (узел ssn в пакете XML). Если обнаружить только один узел ssn не удается, генерируется фатальная ошибка FatalError.

К методу validateEmployeeXML() можно добавить дополнительные проверки. Например, подтверждение того, что узел ssn содержит действительный номер или что служащий имеет хотя бы один телефонный номер и адрес электронной почты, а также что оба значения являются действительными. Можно также модифицировать XML таким образом, что каждый служащий и его менеджер будут иметь уникальные идентификационные номера.

Определение класса ApplicationError

Класс ApplicationError служит основой для классов FatalError и WarningError. Класс ApplicationError является расширением класса Error. Он определяет свои специальные методы и свойства, включая идентификаторы ошибок и степень их серьезности, а также объект XML, содержащий коды и сообщения пользовательских ошибок. Этот класс также включает две статические постоянные, которые используются для определения степени серьезности для каждого типа ошибок.

Метод конструктора класса ApplicationError имеет следующую структуру:

public function ApplicationError() 
{ 
    messages =  
        <errors> 
            <error code="9000"> 
                <![CDATA[Employee must be assigned to a cost center.]]> 
            </error> 
            <error code="9001"> 
                <![CDATA[Employee must be assigned to only one cost center.]]> 
            </error> 
            <error code="9002"> 
                <![CDATA[Employee must have one and only one SSN.]]> 
            </error> 
            <error code="9999"> 
                <![CDATA[The application has been stopped.]]> 
            </error> 
        </errors>; 
}

Каждый узел ошибки в объекте XML содержит уникальный числовой код и сообщение об ошибке. Сообщения об ошибках легко просмотреть по их коду с помощью E4X, как показано в следующем методе getMessageText():

public function getMessageText(id:int):String 
{ 
    var message:XMLList = messages.error.(@code == id); 
    return message[0].text(); 
}

Метод getMessageText() принимает один целочисленный аргумент id и возвращает строку. Аргумент id является кодом ошибки, по которому эту ошибку можно найти. Например, поиск по id 9001 выдает ошибку, в сообщении которой говорится, что каждый служащий должен приписываться только к одному центру учета затрат. Если несколько ошибок имеют одинаковый код, ActionScript возвращает сообщение об ошибке только для первого найденного результата (message[0] в возвращенном объекте XMLList).

Следующий метод в этом классе, а именно getTitle(), не принимает никаких параметров и возвращает строковое значение, содержащее идентификатор для данной специфической ошибки. Это значение позволяет пользователю легко определить, какая именно ошибка произошла в процессе проверки пакета XML. Следующий фрагмент демонстрирует метод getTitle():

public function getTitle():String 
{ 
    return "Error #" + id; 
}

Последним методом в классе ApplicationError является toString(). Этот метод заменяет функцию, определенную в классе Error, позволяя настроить передачу сообщения об ошибке. Этот метод возвращает строку, которая определяет номер специфической ошибки и сообщение о том, что произошло.

public override function toString():String 
{ 
    return "[APPLICATION ERROR #" + id + "] " + message; 
}

Определение класса FatalError

Класс FatalError является расширением пользовательского класса ApplicationError. Он определяет три метода: конструктор FatalError, getTitle() и toString(). Первый метод, конструктор FatalError, принимает один целочисленный аргумент, errorID, задает степень серьезности ошибки с помощью значений статической постоянной, определенной в классе ApplicationError, и получает сообщение о специфической ошибке, вызывая метод getMessageText() класса ApplicationError. Конструктор FatalError имеет следующую структуру:

public function FatalError(errorID:int) 
{ 
    id = errorID; 
    severity = ApplicationError.FATAL; 
    message = getMessageText(errorID); 
}

Следующий метод в классе FatalError, getTitle(), заменяет метод getTitle(), определенный ранее в классе ApplicationError, и дополняет текст заголовком «FATAL», уведомляя таким образом пользователя о фатальной ошибке. Метод getTitle() имеет следующую структуру:

public override function getTitle():String 
{ 
    return "Error #" + id + " -- FATAL"; 
}

Последний метод в этом классе, toString(), заменяет метод toString(), определенный в классе ApplicationError. Метод toString() имеет следующую структуру:

public override function toString():String 
{ 
    return "[FATAL ERROR #" + id + "] " + message; 
}

Определение класса WarningError

Класс WarningError является расширением класса ApplicationError. Он практически идентичен классу FatalError, за исключением пары небольших изменений в строках и установки серьезности ошибки ApplicationError.WARNING вместо ApplicationError.FATAL, как показано в следующем коде:

public function WarningError(errorID:int) 
{ 
    id = errorID; 
    severity = ApplicationError.WARNING; 
    message = super.getMessageText(errorID); 
}