Extended Diagnostic Message R←⎕DMX

⎕DMX is a system object that provides information about the last reported APL error. ⎕DMX has thread scope, i.e. its value differs according to the thread from which it is referenced. In a multi-threaded application therefore, each thread has its own value of ⎕DMX.

⎕DMX contains the following Properties (name class 2.6). Note that this list is likely to change. Your code should not assume that this list will remain unchanged. You should also not assume that the display form of ⎕DMX will remain unchanged.

Category character vector The category of the error
DM nested vector Diagnostic message. This is the same as ⎕DM, but thread safe
EM character vector Event message; this is the same as ⎕EM ⎕EN
EN integer Error number. This is the same as ⎕EN, but thread safe
ENX integer Sub-error number
HelpURL character vector URL of a web page that will provide help for this error. APL identifies and has a handler for URLs starting with http:, https:, mailto: and www. This list may be extended in future
InternalLocation nested vector Identifies the line of interpreter source code (file name and line number) which raised the error. This information may be useful to Dyalog support when investigating an issue
Message character vector Further information about the error
OSError see below If applicable, identifies the error generated by the Operating System or by a child process
Vendor character vector For system generated errors, Vendor will always contain the character vector 'Dyalog'. This value can be set using ⎕SIGNAL

OSError is a 3-element vector whose items are as follows:

1 integer This indicates how an error from the operating system or a child process was retrieved.
0 = by the C-library errno() function
1 = by the Windows GetLastError() function
2 = as the exit status of a child process
2 integer Error code. The error number returned by the operating system using errno() or GetLastError() as above
3 character vector The description of the error returned by the operating system

Example

      1÷0
DOMAIN ERROR
      1÷0
     ∧
      ⎕DMX
 EM       DOMAIN ERROR                              
 Message  Divide by zero                            
 
      ⎕DMX.InternalLocation
 arith_su.c  554

Isolation of Handled Errors

⎕DMX cannot be explicitly localised in the header of a function. However, for all trapped errors, the interpreter creates an environment which effectively makes the current instance of ⎕DMX local to, and available only for the duration of, the trap-handling code.

With the exception of ⎕TRAP with Cutback, ⎕DMX is implicitly localised within:

and is implicitly un-localised when:

During this time, if an error occurs then the localised ⎕DMX is updated to reflect the values generated by the error.

The same is true for ⎕TRAP with Cutback, with the exception that if the cutback trap event is triggered, the updated values for ⎕DMX are preserved until the function that set the cutback trap terminates.

The benefit of the localisation strategy is that code which uses error trapping as a standard operating procedure (such as a file utility which traps FILE NAME ERROR and creates missing files when required) will not pollute the environment with irrelevant error information.

Example

     ∇ tie←NewFile name
[1]    :Trap 22
[2]        tie←name ⎕FCREATE 0
[3]    :Else
[4]        ⎕DMX
[5]        tie←name ⎕FTIE 0
[6]        name ⎕FERASE tie
[7]        tie←name ⎕FCREATE 0
[8]    :EndTrap
[9]    ⎕FUNTIE tie
     ∇

⎕DMX is cleared by )RESET:

      )reset
      ⍴⎕FMT ⎕DMX
0 0

Note: ⎕SIGNAL can be used to reset the value of this system constant.

The first time we run NewFile 'pete', the file doesn't exist and the ⎕FCREATE in NewFile[2] succeeds.

      NewFile 'pete'
1

If we run the function again, the ⎕FCREATE in NewFile[2]generates an error which triggers the :Else clause of the :Trap. On entry to the :Else clause, the values in ⎕DMX reflect the error generated by ⎕FCREATE. The file is then tied, erased and recreated.

 EM       FILE NAME ERROR                                       
 Message  File exists

After exiting the :Trap control structure, the shadowed value of ⎕DMX is discarded, revealing the original value that it shadowed.

      ⍴⎕FMT ⎕DMX
0 0

Example

The EraseFile function also uses a :Trap in order to ignore the situation when the file doesn't exist.

     ∇ EraseFile name;tie
[1]    :Trap 22
[2]        tie←name ⎕FTIE 0
[3]        name ⎕FERASE tie
[4]    :Else
[5]        ⎕DMX
[6]    :EndTrap
     ∇

The first time we run the function, it succeeds in tieing and then erasing the file.

      EraseFile 'pete'

The second time, the ⎕FTIE fails. On entry to the :Else clause, the values in ⎕DMX reflect this error.

      EraseFile 'pete'
 EM       FILE NAME ERROR                                        
 Message  Unable to open file                                    
 OSError  1 2  The system cannot find the file specified.        

Once again, the local value of ⎕DMX is discarded on exit from the :Trap, revealing the shadowed value as before.

      ⍴⎕FMT ⎕DMX
0 0

Example

In this example only the error number (EN) property of ⎕DMX is displayed in order to simplify the output:

     ∇ foo n;⎕TRAP
[1]    'Start foo'⎕DMX.EN
[2]    ⎕TRAP←(2 'E' '→err')(11 'C' '→err')
[3]    goo n
[4]   err:'End foo:'⎕DMX.EN
     ∇

     ∇ goo n;⎕TRAP
[1]    ⎕TRAP←5 'E' '→err'
[2]    ⍎n⊃'÷0' '1 2+1 2 3' '∘'
[3]   err:'goo:'⎕DMX.EN
     ∇

In the first case a DOMAIN ERROR (11) is generated on goo[2]. This error is not included in the definition of ⎕TRAP in goo, but rather the Cutback ⎕TRAP definition in foo. The error causes the stack to be cut back to foo, and then execution branches to foo[4]. Thus ⎕DMX.EN in foo retains the value set when the error occurred in goo.

      foo 1
 Start foo  0
 End foo:  11
   

In the second case a LENGTH ERROR (5) is raised on goo[2]. This error is included in the definition of ⎕TRAP in goo so the value ⎕DMX.EN while in goo is 5, but when goo terminates and foo resumes execution the value of ⎕DMX.EN localised in goo is lost.

      foo 2
 Start foo  0
 goo:  5
 End foo:  0

In the third case a SYNTAX ERROR (2) is raised on goo[2]. Since the ⎕TRAP statement is handled within goo (although the applicable ⎕TRAP is defined in foo), the value ⎕DMX.EN while in goo is 2, but when goo terminates and foo resumes execution the value of ⎕DMX.EN localised in goo is lost.

      foo 3
 Start foo  0
 goo:  2
 End foo:  0