Получите информацию об исключениях

Обзор

То, когда MATLAB выдает исключение, он получает информацию о том, что вызвало ошибку в структуре данных, вызвало объект MException. Этот объект является экземпляром класса MException MATLAB. Можно получить доступ к объекту MException путем ловли исключения перед прерываниями выполнения программы и доступа к объекту, созданному для этой конкретной ошибки через команду catch. При выдаче исключения в ответ на ошибку в собственном коде необходимо будет создать новый объект MException и хранить информацию об ошибке в том объекте.

В этом разделе описываются класс MException и объекты, созданные из того класса:

Информация о том, как использовать этот класс, представлена в более поздних разделах по, Отвечают на Исключение и Выдают Исключение.

Класс MException

Фигура, показанная ниже, иллюстрирует одну возможную настройку объекта класса MException. Объект имеет четыре свойства: identifier, message, stack и cause. Каждое из этих свойств реализовано как поле структуры, которая представляет объект MException. Поле stack является массивом N-1 дополнительных структур, каждый идентифицирующий функцию и номер строки от стека вызовов. Поле cause является массивом ячеек M-1 объектов MException, каждый представляющий исключение, которое связано с текущим.

См. Свойства Класса MException для полного описания этих свойств.

Конструктор Object

Любой код, который обнаруживает ошибку и выдает исключение, должен также создать объект MException, в котором можно записать и передать информацию об ошибке. Синтаксис конструктора MException

ME = MException(identifier, message)

где identifier является идентификатором сообщения MATLAB формы

component:mnemonic

это заключено в одинарные кавычки, и message является текстом, также заключенным в одинарные кавычки, который описывает ошибку. Вывод ME является получившимся объектом MException.

Если вы отвечаете на исключение вместо того, чтобы выдать один, вы не должны создавать объект MException. Объект был уже создан и заполнен кодом, который первоначально обнаружил ошибку.

Свойства класса MException

Класс MException имеет четыре свойства. Каждое из этих свойств реализовано как поле структуры, которая представляет объект MException. Каждое из этих свойств описано в разделах ниже и сослано в разделах по, Отвечают на Исключение и Выдают Исключение. Все только для чтения; их значения не могут быть изменены.

Свойства MException:

Если вы вызываете функцию surf без входных параметров, MATLAB выдает исключение. Если вы отлавливаете исключение, вы видите четыре свойства структуры объекта MException. (Этот пример использует try/catch нетипичным способом. Смотрите раздел по Оператору попытки/выгоды для получения дополнительной информации об использовании try/catch).

try
    surf
catch ME
    ME
end

Запустите это в командной строке, и MATLAB возвращает содержимое объекта MException:

ME =
	MException object with properties:

    identifier: 'MATLAB:narginchk:notEnoughInputs'
       message: 'Not enough input arguments.'
         stack: [1x1 struct]
         cause: {}

Поле stack показывает имя файла, функцию и номер строки, где исключение было выдано:

ME.stack
ans = 
    file: 'matlabroot\toolbox\matlab\graph3d\surf.m'
    name: 'surf'
    line: 54

Поле cause пусто в этом случае. Каждое поле описано более подробно в разделах, которые следуют.

Идентификаторы сообщений

Идентификатор сообщения является тегом, который вы присоединяете к ошибке или предупреждению оператора, что совершает ту ошибку или предупреждение исключительно распознаваемого MATLAB. Можно использовать идентификаторы сообщений с сообщением об ошибке, чтобы лучше идентифицировать источник ошибки, или с предупреждениями управлять любым выбранным подмножеством предупреждений в программах.

Идентификатор сообщения является вектором символа только для чтения, который задает компонент и мнемоническую метку для ошибки или предупреждения. Формат простого идентификатора

component:mnemonic

Двоеточие разделяет две части идентификатора: component и mnemonic. Если идентификатор использует больше чем один component, то дополнительные двоеточия требуются, чтобы разделять их. Идентификатор сообщения должен всегда содержать по крайней мере одно двоеточие.

Некоторые примеры идентификаторов сообщений

MATLAB:rmpath:DirNotFound
MATLAB:odearguments:InconsistentDataType
Simulink:actionNotTaken
TechCorp:OpenFile:notFoundInPath

Оба поля component и mnemonic должны придерживаться следующих синтаксических правил:

  • Никакой пробел (пробелы или символы табуляции) не позволен нигде в идентификаторе.

  • Первый символ должен быть алфавитным, или прописным или строчным.

  • Оставшиеся символы могут быть алфавитно-цифровыми или подчеркивание.

Нет никакого ограничения длины или к component или к mnemonic. Идентификатор может также быть пустым символьным вектором.

Поле компонента.  Поле component задает широкую категорию, под которой могут быть сгенерированы различные ошибки и предупреждения. Общие компоненты являются конкретным продуктом или именем тулбокса, таким как MATLAB или Control, или возможно имя вашей компании, такой как TechCorp в предыдущем примере.

Можно также использовать это поле, чтобы задать многоуровневый компонент. Следующий оператор имеет трехуровневый компонент, сопровождаемый мнемонической меткой:

TechCorp:TestEquipDiv:Waveform:obsoleteSyntax

Поле компонента позволяет вам гарантировать уникальность каждого идентификатора. Таким образом, в то время как внутренний код MATLAB может использовать определенный идентификатор предупреждения как MATLAB:InconsistentDataType, который не устраняет вас от использования той же мнемосхемы, пока вы предшествуете ему с уникальным компонентом. Например,

warning('TechCorp:InconsistentDataType', ...
   'Value %s is inconsistent with existing properties.' ...
   sprocketDiam)

Мнемоническое Поле.  Поле mnemonic обычно используется в качестве тега, относящегося к конкретному сообщению. Например, при создании отчетов об ошибке, следующей из использования неоднозначного синтаксиса, простой компонент и мнемосхема, такая как следующее могут быть соответствующими:

MATLAB:ambiguousSyntax

Идентификаторы сообщений в Объекте MException.  При выдаче исключения создайте соответствующий идентификатор и сохраните его в объект MException в то время, когда вы создаете объект с помощью синтаксиса

ME = MException(identifier, text)

Например,

ME = MException('AcctError:NoClient', ...
      'Client name not recognized.');

ME.identifier
ans =
    AcctError:NoClient

При ответе на исключение можно извлечь идентификатор сообщения от объекта MException как показано здесь. Используя пример surf снова,

try
    surf
catch ME
    id = ME.identifier
end

id =
    MATLAB:narginchk:notEnoughInputs

Текст сообщения об ошибке

Сообщение об ошибке в MATLAB является вектором символа только для чтения, выпущенным кодом программы, и возвратилось в объекте MException. Это сообщение может помочь пользователю в определении причины, и возможно средства, отказа.

При выдаче исключения сочините соответствующее сообщение об ошибке и сохраните его в объект MException в то время, когда вы создаете объект с помощью синтаксиса

ME = MException(identifier, text)

Если ваше сообщение требует, чтобы спецификации форматирования, как доступные с функцией sprintf, использовали этот синтаксис для конструктора MException:

ME = MException(identifier, formatstring, arg1, arg2, ...)

Например,

S = 'Accounts';  f1 = 'ClientName';
ME = MException('AcctError:Incomplete', ...
      'Field ''%s.%s'' is not defined.', S, f1);

ME.message
ans =
    Field 'Accounts.ClientName' is not defined.

При ответе на исключение можно извлечь сообщение об ошибке от объекта MException можно следующим образом:

try
    surf
catch ME
    msg = ME.message
end

msg =
    Not enough input arguments.

Стек вызовов

Поле stack объекта MException идентифицирует номер строки, функцию и имя файла, где ошибка была обнаружена. Если ошибка происходит в вызванной функции, когда в следующем примере, поле stack содержит номер строки, имя функции и имя файла не только для местоположения мгновенной ошибки, но также и для каждой из функций вызова. В этом случае stack является массивом N-1, где N представляет глубину стека вызовов. Таким образом, поле стека отображает имя функции и номер строки, где исключение произошло, имя и номер строки вызывающей стороны, вызывающей стороны вызывающей стороны, и т.д., пока самая верхняя функция не достигнута.

При выдаче исключения MATLAB хранит информацию стека вызовов в поле stack. Вы не можете записать в это поле; доступ только для чтения.

Например, предположите, что у вас есть три функции, которые находятся в двух отдельных файлах:

 mfileA.m
=========================
        .
        .
42 function A1(x, y)
43 B1(x, y);



 mfileB.m
=========================
        .
        .
 8 function B1(x, y)
 9 B2(x, y)
        .
        .
26 function B2(x, y)
27      .
28      .
29      .
30      .
31 %  Throw exception here

Отловите исключение в переменном ME и затем исследуйте поле stack:

for k=1:length(ME.stack)
    ME.stack(k)
end

ans = 
    file: 'C:\matlab\test\mfileB.m'
    name: 'B2'
    line: 31
ans = 
    file: 'C:\matlab\test\mfileB.m'
    name: 'B1'
    line: 9
ans = 
    file: 'C:\matlab\test\mfileA.m'
    name: 'A1'
    line: 43

Массив причины

В некоторых ситуациях может быть важно записать информацию о не только одна команда, которая заставила выполнение останавливаться, но также и другие исключения, которые отловил ваш код. Можно сохранить эти дополнительные объекты MException в поле cause первичного исключения.

Поле cause MException является дополнительным массивом ячеек связанных объектов MException. Необходимо использовать следующий синтаксис при добавлении объектов к массиву ячеек cause:

primaryException = addCause(primaryException, secondaryException)

Этот пример пытается присвоить массив D переменному X. Если массив D не существует, код пытается загрузить его из MAT-файла и затем повторяет присвоение его к X. Если загрузка перестала работать, новый объект MException (ME3) создается, чтобы сохранить причину первых двух ошибок (ME1 и ME2):

try
    X = D(1:25)
catch ME1
    try
        filename = 'test200';
        load(filename);
        X = D(1:25)
    catch ME2
        ME3 = MException('MATLAB:LoadErr', ...
               'Unable to load from file %s', filename);
        ME3 = addCause(ME3, ME1);
        ME3 = addCause(ME3, ME2);
    end
end

Существует два исключения в поле причины ME3:

ME3.cause
ans = 
    [1x1 MException]
    [1x1 MException]

Исследуйте поле cause ME3, чтобы видеть связанные ошибки:

ME3.cause{:}
ans =

	MException object with properties:

    identifier: 'MATLAB:UndefinedFunction'
       message: 'Undefined function or method 'D' for input 
arguments of type 'double'.'
         stack: [0x1 struct]
         cause: {}
ans =

	MException object with properties:

    identifier: 'MATLAB:load:couldNotReadFile'
       message: 'Unable to read file test204: No such file or 
directory.'
         stack: [0x1 struct]
         cause: {}

Методы класса MException

Существует десять методов, которые можно использовать с классом MException. Имена этих методов являются чувствительными к регистру. Смотрите страницы с описанием функции MATLAB для получения дополнительной информации.

MethodName Описание
MException.addCauseДобавьте MException к полю cause другого MException.
MException.getReportВозвратите форматированное сообщение на основе текущего исключения.
MException.lastВозвратите последнее неперехваченное исключение. Это - статический метод.
MException.rethrowПереиздайте исключение, которое было ранее отловлено.
MException.throwВыпустите исключение.
MException.throwAsCallerВыпустите исключение, но не используйте текущий стековый фрейм от поля stack.
Была ли эта тема полезной?