Eugeny KhanchinHandling error/warning/info messages in SKILL
In programming, effective communication with users and robust error handling are essential for creating reliable and user-friendly applications.
Providing immediate feedback and guidance helps users understand what the script does and decide what to do next. By reporting errors and warnings, we can help users to diagnose and resolve issues.
This guide provides an overview of messaging and debugging functions in SKILL, including hiDisplayAppDBox(), error(), warn(), and info(). These functions are essential for communicating with users, handling errors, and providing informational messages within the Cadence Virtuoso environment.
1. Function - hiDisplayAppDBox()
This function displays a pop-up box with a custom message. It can be used to display error, warning, informational or dialog messages.
Use hiDisplayAppDBox() when you need to interact with the user through the GUI, such as confirming an action, displaying an error that requires user acknowledgment, or providing important information. We can customize the pop-up box with optional arguments like message text, box type, buttons, etc., to match our needs.
1/*
2Functions that show how to use dialog box for various cases, like error, warning, info and dialog messages.
3
4Author: Eugeny Khanchin
5Source: AnalogHub.ie
6*/
7
8
9procedure( writeData(filePath data)
10 /*
11 An example of using error message box to indicate that the file
12 couldn't be open or the type of provided data is not a string.
13 */
14 prog( (outPort message)
15
16 outPort = outfile(filePath "w")
17 unless( outPort
18 sprintf(message "Failed to open a \"%s\" file!\nPlease check that the provided path is correct and you have write permissions."
19 filePath)
20 hiDisplayAppDBox(
21 ?name 'errorAppDBox
22 ?dboxBanner "*ERROR* Writing Data"
23 ?dboxText message
24 ?dialogType hicErrorDialog
25 ?buttonLayout 'Close
26 )
27
28 return()
29 );unless
30
31 unless( stringp(data)
32 sprintf(message "The provided data type - %L.\nPlease provide data as a string!"
33 type(data))
34
35 hiDisplayAppDBox(
36 ?name 'errorAppDBox
37 ?dboxBanner "*ERROR* Writing Data"
38 ?dboxText message
39 ?dialogType hicErrorDialog
40 ?buttonLayout 'Close
41 )
42
43 return()
44 );unless
45
46 fprintf(outPort "%s\n" data)
47 close(outPort)
48
49 return(t)
50 );prog
51);procedure
52
53
54procedure( runVerifications()
55 /*
56 An example of using a warning message box to indicate that an
57 environment variable is missing, but still can continue to run the code.
58 */
59 let( (message)
60
61 unless( getShellEnvVar("NETBATCH_POOL")
62 message = "Netbatch settings are missing!\nRunning the tasks locally."
63 hiDisplayAppDBox(
64 ?name 'warningAppDBox
65 ?dboxBanner "*WARNING* My App"
66 ?dboxText message
67 ?dialogType hicWarningDialog
68 ?buttonLayout 'Close
69 )
70 );unless
71
72 ; Rest of the code here
73 );let
74);procedure
75
76
77procedure( runTask()
78 /*
79 An example of using info message box to indicate
80 that the task is finished.
81 */
82 let( (message success)
83
84 ; Implement task logic here
85
86 if( success
87 then
88 message = "The task is finished successfully!"
89 else
90 message = "The task is finished with errors!\nPlease refer to a log file."
91 );if
92
93 hiDisplayAppDBox(
94 ?name 'infoAppDBox
95 ?dboxBanner "*INFO* My App"
96 ?dboxText message
97 ?dialogType hicMessageDialog
98 ?buttonLayout 'Close
99 )
100 );let
101);procedure
102
103
104procedure( askUser()
105 /*
106 An example of using a dialog box to indicate what user wants to do next.
107 */
108 let( (answer)
109
110 answer = hiDisplayAppDBox(
111 ?name 'questionAppDBox
112 ?dboxBanner "*QUESTION* My App"
113 ?dboxText "A file is missing!\nYou can either create a new one, continue or abort."
114 ?dialogType hicQuestionDialog
115 ?buttonLayout 'UserDefined
116 ?buttons list("Create New File" "Continue" "Abort")
117 ?callback list("createNewFile()" nil "abort()")
118 )
119
120 ; If you're using ?callback, then the "answer" will get "t"
121 case( answer
122 ( 1
123 printf("Creating a new file\n")
124 )
125 ( 2
126 printf("Continuing\n")
127 )
128 ( 3
129 printf("Aborting\n")
130 )
131 );case
132 );let
133);procedure
134
135
136procedure( createNewFile()
137 printf("Running a callback function to create a new file\n")
138);procedure
139
140
141procedure( abort()
142 printf("Running a callback function to abort\n")
143);procedure
144
145
146procedure( displayInfoMessage(@key (title "INFO")
147 (message "Placeholder text") (parent nil))
148 /*
149 Displays an informational message box, optionally centered relative
150 to a parent form.
151
152 Example usage:
153 displayInfoMessage(
154 ?title "*INFO* My Info"
155 ?message "This is an info message"
156 ?parent myForm
157 )
158
159 @param title string
160 The title of the dialog box, displayed in the banner. Defaults to "INFO".
161
162 @param message string
163 The message text to be displayed within the dialog box. Defaults to
164 "Placeholder text".
165
166 @param parent form/nil
167 An optional parent form. If provided, the dialog box will be centered
168 relative to this form. If 'nil', the dialog box will appear at the
169 default location.
170 */
171 let( (location)
172
173 when( parent
174 location = getParentCenterPoint(parent)
175 );when
176
177 hiDisplayAppDBox(
178 ?name 'infoAppDBox
179 ?dboxBanner title
180 ?dboxText message
181 ?dialogType hicMessageDialog
182 ?buttonLayout 'Close
183 ?location location
184 )
185 );let
186);procedure
187
188
189procedure( displayWarningMessage(@key (title "WARNING")
190 (message "Placeholder text") (parent nil))
191 /*
192 Displays a warning message box, optionally centered relative to a
193 parent form.
194
195 Example usage:
196 displayWarningMessage(
197 ?title "*WARNING* My Warning"
198 ?message "This is a warning message"
199 ?parent myForm
200 )
201
202 @param title string
203 The title of the dialog box, displayed in the banner. Defaults to
204 "WARNING".
205
206 @param message string
207 The message text to be displayed within the dialog box. Defaults to
208 "Placeholder text".
209
210 @param parent form/nil
211 An optional parent form. If provided, the dialog box will be centered
212 relative to this form. If 'nil', the dialog box will appear at the
213 default location.
214 */
215 let( (location)
216
217 when( parent
218 location = getParentCenterPoint(parent)
219 );when
220
221 hiDisplayAppDBox(
222 ?name 'warningAppDBox
223 ?dboxBanner title
224 ?dboxText message
225 ?dialogType hicWarningDialog
226 ?buttonLayout 'Close
227 ?location location
228 )
229 );let
230);procedure
231
232
233procedure( displayErrorMessage(@key (title "ERROR")
234 (message "Placeholder text") (parent nil))
235 /*
236 Displays an error message box, optionally centered relative to a
237 parent form.
238
239 Example usage:
240 displayErrorMessage(
241 ?title "*ERROR* My Error"
242 ?message "This is an error message"
243 ?parent myForm
244 )
245
246 @param title string
247 The title of the dialog box, displayed in the banner. Defaults to
248 "ERROR".
249
250 @param message string
251 The message text to be displayed within the dialog box. Defaults to
252 "Placeholder text".
253
254 @param parent form/nil
255 An optional parent form. If provided, the dialog box will be centered
256 relative to this form. If 'nil', the dialog box will appear at the
257 default location.
258 */
259 let( (location)
260
261 when( parent
262 location = getParentCenterPoint(parent)
263 );when
264
265 hiDisplayAppDBox(
266 ?name 'errorAppDBox
267 ?dboxBanner title
268 ?dboxText message
269 ?dialogType hicErrorDialog
270 ?buttonLayout 'Close
271 ?location location
272 )
273 );let
274);procedure
275
276
277procedure( getParentCenterPoint(parent)
278 /*
279 Calculates the center point of a given parent form.
280
281 @param parent form
282 The parent form whose center point is to be calculated. This form
283 should have retrievable location and size properties.
284
285 @return list
286 Returns a list containing the x and y coordinates of the center point
287 of the parent form.
288 */
289 let( (formLocation x y formSize width height)
290
291 formLocation = hiGetFormLocation(parent)
292 x = car(formLocation)
293 y = cadr(formLocation)
294 formSize = hiGetFormSize(parent)
295 width = car(formSize)
296 height = cadr(formSize)
297
298 x+width/2:y+height/2
299 );let
300);procedure

Example using hiDisplayAppDBox() function
2. Display an error message
Errors should prevent a user from continuing using a script if something went wrong. They should be clear, so the user understands why the script failed and what to do next.
For example, failing to write to a file or providing incorrect type of input:
1procedure( writeData(filePath data)
2prog( (outPort message)
3
4outPort = outfile(filePath "w")
5unless( outPort
6sprintf(message "Failed to open a \\"%s\\" file!\nPlease check that the provided path is correct and you have write permissions."
7filePath)
8hiDisplayAppDBox(
9?name 'errorAppDBox
10?dboxBanner "*ERROR* Writing Data"
11?dboxText message
12?dialogType hicErrorDialog
13?buttonLayout 'Close
14)
15
16return()
17);unless
18
19unless( stringp(data)
20sprintf(message "The provided data type - %L.\nPlease provide data as a string!"
21type(data))
22
23hiDisplayAppDBox(
24?name 'errorAppDBox
25?dboxBanner "*ERROR* Writing Data"
26?dboxText message
27?dialogType hicErrorDialog
28?buttonLayout 'Close
29)
30
31return()
32);unless
33
34fprintf(outPort "%s\n" data)
35close(outPort)
36
37return(t)
38);prog
39);procedure

Example of an error message
Note: The code after the hiDisplayAppDBox() function is executed, so make sure to exit/stop a function after showing an error message.
3. Display a warning message
Warnings inform users of conditions that might lead to problems but do not immediately prevent the script from continuing.
For example, when the netbatch/cloud settings are missing, but we can still run the script locally:
1procedure( runVerifications()
2let( (message)
3
4unless( getShellEnvVar("NETBATCH_POOL")
5message = "Netbatch settings are missing!\nRunning the tasks locally."
6hiDisplayAppDBox(
7?name 'warningAppDBox
8?dboxBanner "*WARNING* My App"
9?dboxText message
10?dialogType hicWarningDialog
11?buttonLayout 'Close
12)
13);unless
14
15; Rest of the code here
16);let
17);procedure

Example of a warning message
4. Display an info message
Info messages also do not prevent the script from continuing and are best to communicate progress, confirm actions, and offer guidance and tips.
For example, we inform the user when the script is finished:
1procedure( runTask()
2let( (message success)
3
4; Implement task logic here
5
6if( success
7then
8message = "The task is finished successfully!"
9else
10message = "The task is finished with errors!\nPlease refer to a log file."
11);if
12
13hiDisplayAppDBox(
14?name 'infoAppDBox
15?dboxBanner "*INFO* My App"
16?dboxText message
17?dialogType hicMessageDialog
18?buttonLayout 'Close
19)
20);let
21);procedure

Example of an info message
5. Display a dialog box
Displaying a dialog box is required when you need to interact directly with the user. Dialog boxes are ideal for situations where you need to make selections from the user. This could include entering data, choosing options, or confirming settings.
Before executing actions that have significant consequences, such as deleting data or applying major changes, a dialog box can be used to confirm the user's intent. This helps prevent accidental actions and ensures that the user is aware of the impact.
For example, when we want the user to choose what to do when a file is missing:
1procedure( askUser()
2let( (answer)
3
4answer = hiDisplayAppDBox(
5?name 'questionAppDBox
6?dboxBanner "*QUESTION* My App"
7?dboxText "A file is missing!\nYou can either create a new one, continue or abort."
8?dialogType hicQuestionDialog
9?buttonLayout 'UserDefined
10?buttons list("Create New File" "Continue" "Abort")
11)
12
13case( answer
14( 1
15printf("Creating a new file\n")
16)
17( 2
18printf("Continuing\n")
19)
20( 3
21printf("Aborting\n")
22)
23);case
24);let
25);procedure

Example of a dialog message
Here, we use ?buttons option to define the buttons. hiDisplayAppDBox() returns the number of the button clicked (1-based), which helps us to determine which logic to run after.
You can also provide callbacks to each button directly via the ?callback option:
1procedure( askUser()
2hiDisplayAppDBox(
3?name 'questionAppDBox
4?dboxBanner "*QUESTION* My App"
5?dboxText "A file is missing!\nYou can either create a new one, continue or abort."
6?dialogType hicQuestionDialog
7?buttonLayout 'UserDefined
8?buttons list("Create New File" "Continue" "Abort")
9?callback list("createNewFile()" nil "abort()")
10)
11
12printf("Code continues here\n")
13);procedure
14
15
16procedure( createNewFile()
17printf("Creating a new file\n")
18);procedure
19
20
21procedure( abort()
22printf("Aborting\n")
23);procedureNote: Though, the clicked button runs a dedicated function, the code after the hiDisplayAppDBox() continues to run after the click. Also, if the callback is set to "nil", the button does nothing.
6. Functions - error(), warn() and info()
There is another way to show error, warning and informational messages. These functions print colored messages into the CIW, providing information for debugging without popping a box.
Overview:
- error() - prints an error message and halts the execution of the current script.

Output of the error() function
Note: The error() function halts code execution and prevents any subsequent script code from running.
- warn() - prints a warning message without halting script execution.

Output of the warn() function
- info() - prints an informational message.

Output of the einfo() function
To try these functions, replace hiDisplayAppDBox() with error(), warn(), and info() in the earlier examples for error, warning, and informational messages, respectively.
7. Conclusion
Mastering the use of messaging and debugging functions such as hiDisplayAppDBox(), error(), warn(), and info() is crucial for developing robust and user-friendly applications. These functions provide effective communication with users by providing immediate feedback and guidance. They also enhance error handling, ensuring that scripts run smoothly and efficiently.