Messages

The Wolfram Language has a general mechanism for handling messages generated during computations. Many built-in Wolfram Language functions use this mechanism to produce error and warning messages. You can also use the mechanism for messages associated with functions you write.

The basic idea is that every message has a definite name, of the form symbol::tag. You can use this name to refer to the message. (The object symbol::tag has head (RefLink[MessageName, paclet:ref/MessageName]).)

Controlling the printing of messages.

As discussed in "Warnings and Messages", you can use (RefLink[Quiet, paclet:ref/Quiet]) to control the printing of particular messages during an evaluation. Most messages associated with built-in functions are switched on by default. If you want to suppress a message permanently, you can use (RefLink[Off, paclet:ref/Off]).

This prints a warning message. Also, the front end highlights the extra argument in red:

Log[a,b,c]

This suppresses the warning message:

Quiet[Log[a,b,c]]

The message reappears with the next evaluation:

Log[a,b,c]

You can use (RefLink[On, paclet:ref/On]) and (RefLink[Off, paclet:ref/Off]) to make global changes to the printing of particular messages. You can use (RefLink[Off, paclet:ref/Off]) to switch off a message if you never want to see it.

You can switch off the message like this:

Off[Log::argt]

Now no warning message is produced:

Log[a,b,c]

Although most messages associated with built-in functions are switched on by default, there are some which are switched off by default, and which you will see only if you explicitly switch them on. An example is the message (RefLink[General, paclet:ref/General])::newsym, discussed in "Intercepting the Creation of New Symbols", which tells you every time a new symbol is created.

Manipulating messages.

The text of a message with the name s::tag is stored simply as the value of s::tag, associated with the symbol s. You can therefore see the text of a message simply by asking for s::tag. You can set the text by assigning a value to s::tag.

If you give (RefLink[LinearSolve, paclet:ref/LinearSolve]) a singular matrix, it prints a warning message:

LinearSolve[{{1,1},{2,2}},{3,5}]

Here is the text of the message:

LinearSolve::nosol

This redefines the message:

LinearSolve::nosol="Matrix encountered is not invertible."

Now the new form will be used:

LinearSolve[{{1,1},{2,2}},{3,5}]

Messages are always stored as strings suitable for use with (RefLink[StringForm, paclet:ref/StringForm]). When the message is printed, the appropriate expressions are "spliced" into it. The expressions are wrapped with (RefLink[HoldForm, paclet:ref/HoldForm]) to prevent evaluation. In addition, any function that is assigned as the value of the global variable (RefLink[$MessagePrePrint, paclet:ref/$MessagePrePrint]) is applied to the resulting expressions before they are given to (RefLink[StringForm, paclet:ref/StringForm]). The default for (RefLink[$MessagePrePrint, paclet:ref/$MessagePrePrint]) uses (RefLink[Short, paclet:ref/Short]) for text formatting and a combination of (RefLink[Short, paclet:ref/Short]) and (RefLink[Shallow, paclet:ref/Shallow]) for typesetting.

Most messages are associated directly with the functions that generate them. There are, however, some "general" messages, which can be produced by a variety of functions.

If you give the wrong number of arguments to a function F, the Wolfram Language will warn you by printing a message such as F::argx. If the Wolfram Language cannot find a message named F::argx, it will use the text of the "general" message (RefLink[General, paclet:ref/General])::argx instead. You can use (RefLink[Off, paclet:ref/Off])[F::argx] to switch off the argument count message specifically for the function F. You can also use (RefLink[Off, paclet:ref/Off])[(RefLink[General, paclet:ref/General])::argx] to switch off all messages that use the text of the general message.

The Wolfram Language prints a message if you give the wrong number of arguments to a built-in function:

Sqrt[a,b]

This argument count message is a general one, used by many different functions:

General::argx

Quietening (RefLink[Sqrt, paclet:ref/Sqrt])::argx suppresses the message issued by the (RefLink[Sqrt, paclet:ref/Sqrt]) function but not by other functions.

This prints the (RefLink[Sin, paclet:ref/Sin])::argx message but not (RefLink[Sqrt, paclet:ref/Sqrt])::argx:

Quiet[{Sin[a,b],Sqrt[a,b]},Sqrt::argx]

Quietening (RefLink[General, paclet:ref/General])::argx suppresses all messages that use (RefLink[General, paclet:ref/General])::argx.

Here, no argx messages are printed:

Quiet[{Sin[a,b],Sqrt[a,b]},General::argx]

If F::tag message is not using (RefLink[General, paclet:ref/General])::tag, suppressing (RefLink[General, paclet:ref/General])::tag will not suppress F::tag. For example, turning off the (RefLink[General, paclet:ref/General])::targ message will not turn off the (RefLink[Entropy, paclet:ref/Entropy])::targ message, because those two messages are not one and the same.

(RefLink[Entropy, paclet:ref/Entropy])::targ is not the same as (RefLink[General, paclet:ref/General])::targ:

Entropy[x]

(RefLink[IdentityMatrix, paclet:ref/IdentityMatrix])::targ is the same message as (RefLink[General, paclet:ref/General])::targ:

IdentityMatrix[4,x]

(RefLink[Entropy, paclet:ref/Entropy])::targ message is still printed inside of (RefLink[Quiet, paclet:ref/Quiet]):

Quiet[{Entropy[x],IdentityMatrix[4,x]},General::targ]

If something goes very wrong with a calculation you are doing, it is common to find that the same warning message is generated over and over again. This is usually more confusing than useful. As a result, the Wolfram Language keeps track of all messages that are produced during a particular calculation, and stops printing a particular message if it comes up more than three times. Whenever this happens, the Wolfram Language prints the message (RefLink[General, paclet:ref/General])::stop to let you know. If you really want to see all the messages that the Wolfram Language tries to print, you can do this by switching off (RefLink[General, paclet:ref/General])::stop.

Finding out what messages were produced during a computation.

In every computation you do, the Wolfram Language maintains a list (RefLink[$MessageList, paclet:ref/$MessageList]) of all the messages that are produced. In a standard Wolfram Language session, this list is cleared after each line of output is generated. However, during a computation, you can access the list. In addition, when the n(^th) output line in a session is generated, the value of (RefLink[$MessageList, paclet:ref/$MessageList]) is assigned to (RefLink[MessageList, paclet:ref/MessageList])[n].

This returns (RefLink[$MessageList, paclet:ref/$MessageList]), which gives a list of the messages produced:

Sqrt[a,b,c];Exp[a,b];$MessageList

The message names are wrapped in (RefLink[HoldForm, paclet:ref/HoldForm]) to stop them from evaluating:

InputForm[%]

In writing programs, it is often important to be able to check automatically whether any messages were generated during a particular calculation. If messages were generated, say as a consequence of producing indeterminate numerical results, then the result of the calculation may be meaningless.

Checking for warning messages.

Evaluating 1^0 produces no messages, so the result of the evaluation is returned:

Check[1^0,err]

Evaluating 0^0 produces a message, so the second argument of (RefLink[Check, paclet:ref/Check]) is returned:

Check[0^0,err]

(RefLink[Check, paclet:ref/Check])[expr,failexpr] tests for all messages that are actually printed out. It does not test for messages whose output has been suppressed using (RefLink[Off, paclet:ref/Off]).

In some cases you may want to test only for a specific set of messages, say ones associated with numerical overflow. You can do this by explicitly telling (RefLink[Check, paclet:ref/Check]) the names of the messages you want to look for.

The message generated by (RefLink[Sin, paclet:ref/Sin])[1,2] is ignored by (RefLink[Check, paclet:ref/Check]), since it is not the one specified:

Check[Sin[1,2],err,General::ind]

Generating messages.

By using the function (RefLink[Message, paclet:ref/Message]), you can mimic all aspects of the way in which built-in Wolfram Language functions generate messages. You can for example switch on and off messages using (RefLink[On, paclet:ref/On]) and (RefLink[Off, paclet:ref/Off]), and (RefLink[Message, paclet:ref/Message]) will automatically look for (RefLink[General, paclet:ref/General])::tag if it does not find the specific message s::tag.

This defines the text of a message associated with f:

f::overflow="Factorial argument `1` too large."

Here is the function f:

f[x_]:=If[x>10,(Message[f::overflow,x];Infinity),x!]

When the argument of f is greater than 10, the message is generated:

f[20]

This switches off the message:

Off[f::overflow]

Now the message is no longer generated:

f[20]

When you call (RefLink[Message, paclet:ref/Message]), it first tries to find a message with the explicit name you have specified. If this fails, it tries to find a message with the appropriate tag associated with the symbol (RefLink[General, paclet:ref/General]). If this too fails, then the Wolfram Language takes any function you have defined as the value of the global variable (RefLink[$NewMessage, paclet:ref/$NewMessage]), and applies this function to the symbol and tag of the message you have requested.

By setting up the value of (RefLink[$NewMessage, paclet:ref/$NewMessage]) appropriately, you can, for example, get the Wolfram Language to read in the text of a message from a file when that message is first needed.