@@ -91,7 +91,7 @@ def self.receiver_string(receiver)
91
91
end
92
92
end
93
93
94
- def self . message_and_class ( exception , highlight )
94
+ def self . detailed_message ( exception , highlight )
95
95
message = StringValue exception . message . to_s
96
96
97
97
klass = Primitive . class ( exception ) . to_s
@@ -100,40 +100,78 @@ def self.message_and_class(exception, highlight)
100
100
klass = "#{ klass } : #{ Truffle ::Interop . meta_qualified_name Truffle ::Interop . meta_object ( exception ) } "
101
101
end
102
102
103
+ if message . empty?
104
+ return highlight ? "\n \e [1m#{ klass } \e [m" : klass
105
+ end
106
+
107
+ anonymous_class = Primitive . module_anonymous? ( Primitive . class ( exception ) )
108
+
103
109
if highlight
104
- highlighted_class = " (\e [1;4m#{ klass } \e [m\e [1m)"
110
+ highlighted_class_string = ! anonymous_class ? " (\e [1;4m#{ klass } \e [m\e [1m)" : ''
105
111
if message . include? ( "\n " )
106
112
first = true
107
113
result = +''
108
114
message . each_line do |line |
109
115
if first
110
116
first = false
111
- result << "\e [1m#{ line . chomp } #{ highlighted_class } \e [m"
117
+ result << "\e [1m#{ line . chomp } #{ highlighted_class_string } \e [m"
112
118
else
113
119
result << "\n \e [1m#{ line . chomp } \e [m"
114
120
end
115
121
end
116
122
result
117
123
else
118
- "\e [1m#{ message } #{ highlighted_class } \e [m"
124
+ "\e [1m#{ message } #{ highlighted_class_string } \e [m"
119
125
end
120
126
else
127
+ class_string = !anonymous_class ? " (#{ klass } )" : ''
128
+
121
129
if i = message . index ( "\n " )
122
- "#{ message [ 0 ...i ] } ( #{ klass } ) #{ message [ i ..-1 ] } "
130
+ "#{ message [ 0 ...i ] } #{ class_string } #{ message [ i ..-1 ] } "
123
131
else
124
- "#{ message } ( #{ klass } ) "
132
+ "#{ message } #{ class_string } "
125
133
end
126
134
end
127
135
end
128
136
129
- def self . full_message ( exception , highlight , order )
137
+ def self . detailed_message_or_fallback ( exception , options )
138
+ unless Primitive . respond_to? ( exception , :detailed_message , false )
139
+ return detailed_message_fallback ( exception , options )
140
+ end
141
+
142
+ detailed_message = exception . detailed_message ( **options )
143
+ detailed_message = Truffle ::Type . rb_check_convert_type ( detailed_message , String , :to_str )
144
+
145
+ if !Primitive . nil? ( detailed_message )
146
+ detailed_message
147
+ else
148
+ detailed_message_fallback ( exception , options )
149
+ end
150
+ end
151
+
152
+ def self . detailed_message_fallback ( exception , options )
153
+ class_name = Primitive . class ( exception ) . to_s
154
+
155
+ if options [ :highlight ]
156
+ "\e [1;4m#{ class_name } \e [m\e [1m"
157
+ else
158
+ class_name
159
+ end
160
+ end
161
+
162
+ def self . full_message ( exception , **options )
163
+ highlight = options [ :highlight ]
130
164
highlight = if Primitive . nil? ( highlight )
131
165
Exception . to_tty?
132
166
else
133
167
raise ArgumentError , "expected true of false as highlight: #{ highlight } " unless Primitive . true? ( highlight ) || Primitive . false? ( highlight )
134
168
!Primitive . false? ( highlight )
135
169
end
136
170
171
+ options [ :highlight ] = highlight
172
+
173
+ order = options [ :order ]
174
+ order = :top if Primitive . nil? ( order )
137
175
raise ArgumentError , "expected :top or :bottom as order: #{ order } " unless Primitive . equal? ( order , :top ) || Primitive . equal? ( order , :bottom )
138
176
reverse = !Primitive . equal? ( order , :top )
139
177
@@ -146,28 +184,29 @@ def self.full_message(exception, highlight, order)
146
184
"Traceback (most recent call last):\n "
147
185
end
148
186
result << traceback_msg
149
- append_causes ( result , exception , { } . compare_by_identity , reverse , highlight )
150
- backtrace_message = backtrace_message ( highlight , reverse , bt , exception )
187
+ append_causes ( result , exception , { } . compare_by_identity , reverse , highlight , options )
188
+ backtrace_message = backtrace_message ( highlight , reverse , bt , exception , options )
151
189
if backtrace_message . empty?
152
- result << message_and_class ( exception , highlight )
190
+ result << detailed_message_or_fallback ( exception , options )
153
191
else
154
192
result << backtrace_message
155
193
end
156
194
else
157
- backtrace_message = backtrace_message ( highlight , reverse , bt , exception )
195
+ backtrace_message = backtrace_message ( highlight , reverse , bt , exception , options )
158
196
if backtrace_message . empty?
159
- result << message_and_class ( exception , highlight )
197
+ result << detailed_message_or_fallback ( exception , options )
160
198
else
161
199
result << backtrace_message
162
200
end
163
- append_causes ( result , exception , { } . compare_by_identity , reverse , highlight )
201
+ append_causes ( result , exception , { } . compare_by_identity , reverse , highlight , options )
164
202
end
165
203
result
166
204
end
167
205
168
- def self . backtrace_message ( highlight , reverse , bt , exc )
169
- message = message_and_class ( exc , highlight )
206
+ def self . backtrace_message ( highlight , reverse , bt , exc , options )
207
+ message = detailed_message_or_fallback ( exc , options )
170
208
message = message . end_with? ( "\n " ) ? message : "#{ message } \n "
209
+
171
210
return '' if Primitive . nil? ( bt ) || bt . empty?
172
211
limit = Primitive . exception_backtrace_limit
173
212
limit = limit >= 0 && bt . size - 1 >= limit + 2 ? limit : -1
@@ -192,26 +231,26 @@ def self.backtrace?(exc)
192
231
end
193
232
end
194
233
195
- def self . append_causes ( str , err , causes , reverse , highlight )
234
+ def self . append_causes ( str , err , causes , reverse , highlight , options )
196
235
cause = err . cause
197
236
if !Primitive . nil? ( cause ) && Primitive . is_a? ( cause , Exception ) && !causes . has_key? ( cause )
198
237
causes [ cause ] = true
199
238
if reverse
200
- append_causes ( str , cause , causes , reverse , highlight )
201
- backtrace_message = backtrace_message ( highlight , reverse , cause . backtrace , cause )
239
+ append_causes ( str , cause , causes , reverse , highlight , options )
240
+ backtrace_message = backtrace_message ( highlight , reverse , cause . backtrace , cause , options )
202
241
if backtrace_message . empty?
203
- str << message_and_class ( err , highlight )
242
+ str << detailed_message_or_fallback ( exception , options )
204
243
else
205
244
str << backtrace_message
206
245
end
207
246
else
208
- backtrace_message = backtrace_message ( highlight , reverse , cause . backtrace , cause )
247
+ backtrace_message = backtrace_message ( highlight , reverse , cause . backtrace , cause , options )
209
248
if backtrace_message . empty?
210
- str << message_and_class ( err , highlight )
249
+ str << detailed_message_or_fallback ( exception , options )
211
250
else
212
251
str << backtrace_message
213
252
end
214
- append_causes ( str , cause , causes , reverse , highlight )
253
+ append_causes ( str , cause , causes , reverse , highlight , options )
215
254
end
216
255
end
217
256
end
@@ -250,8 +289,8 @@ def self.to_class_name(val)
250
289
end
251
290
end
252
291
253
- def self . get_formatted_backtrace ( exc )
254
- full_message ( exc , nil , :top )
292
+ def self . get_formatted_backtrace ( exception )
293
+ full_message ( exception , highlight : nil , order : :top )
255
294
end
256
295
257
296
def self . comparison_error_message ( x , y )
0 commit comments