github.com/lulzWill/go-agent@v2.1.2+incompatible/internal_errors_test.go (about) 1 package newrelic 2 3 import ( 4 "runtime" 5 "strconv" 6 "testing" 7 8 "github.com/lulzWill/go-agent/internal" 9 ) 10 11 type myError struct{} 12 13 func (e myError) Error() string { return "my msg" } 14 15 func TestNoticeErrorBackground(t *testing.T) { 16 app := testApp(nil, nil, t) 17 txn := app.StartTransaction("hello", nil, nil) 18 err := txn.NoticeError(myError{}) 19 if nil != err { 20 t.Error(err) 21 } 22 txn.End() 23 app.ExpectErrors(t, []internal.WantError{{ 24 TxnName: "OtherTransaction/Go/hello", 25 Msg: "my msg", 26 Klass: "newrelic.myError", 27 Caller: "go-agent.TestNoticeErrorBackground", 28 URL: "", 29 }}) 30 app.ExpectErrorEvents(t, []internal.WantEvent{{ 31 Intrinsics: map[string]interface{}{ 32 "error.class": "newrelic.myError", 33 "error.message": "my msg", 34 "transactionName": "OtherTransaction/Go/hello", 35 }, 36 }}) 37 app.ExpectMetrics(t, backgroundErrorMetrics) 38 } 39 40 func TestNoticeErrorWeb(t *testing.T) { 41 app := testApp(nil, nil, t) 42 txn := app.StartTransaction("hello", nil, helloRequest) 43 err := txn.NoticeError(myError{}) 44 if nil != err { 45 t.Error(err) 46 } 47 txn.End() 48 app.ExpectErrors(t, []internal.WantError{{ 49 TxnName: "WebTransaction/Go/hello", 50 Msg: "my msg", 51 Klass: "newrelic.myError", 52 Caller: "go-agent.TestNoticeErrorWeb", 53 URL: "/hello", 54 }}) 55 app.ExpectErrorEvents(t, []internal.WantEvent{{ 56 Intrinsics: map[string]interface{}{ 57 "error.class": "newrelic.myError", 58 "error.message": "my msg", 59 "transactionName": "WebTransaction/Go/hello", 60 }, 61 }}) 62 app.ExpectMetrics(t, webErrorMetrics) 63 } 64 65 func TestNoticeErrorTxnEnded(t *testing.T) { 66 app := testApp(nil, nil, t) 67 txn := app.StartTransaction("hello", nil, nil) 68 txn.End() 69 err := txn.NoticeError(myError{}) 70 if err != errAlreadyEnded { 71 t.Error(err) 72 } 73 txn.End() 74 app.ExpectErrors(t, []internal.WantError{}) 75 app.ExpectErrorEvents(t, []internal.WantEvent{}) 76 app.ExpectMetrics(t, backgroundMetrics) 77 } 78 79 func TestNoticeErrorHighSecurity(t *testing.T) { 80 cfgFn := func(cfg *Config) { cfg.HighSecurity = true } 81 app := testApp(nil, cfgFn, t) 82 txn := app.StartTransaction("hello", nil, nil) 83 err := txn.NoticeError(myError{}) 84 if nil != err { 85 t.Error(err) 86 } 87 txn.End() 88 app.ExpectErrors(t, []internal.WantError{{ 89 TxnName: "OtherTransaction/Go/hello", 90 Msg: highSecurityErrorMsg, 91 Klass: "newrelic.myError", 92 Caller: "go-agent.TestNoticeErrorHighSecurity", 93 }}) 94 app.ExpectErrorEvents(t, []internal.WantEvent{{ 95 Intrinsics: map[string]interface{}{ 96 "error.class": "newrelic.myError", 97 "error.message": highSecurityErrorMsg, 98 "transactionName": "OtherTransaction/Go/hello", 99 }, 100 }}) 101 app.ExpectMetrics(t, backgroundErrorMetrics) 102 } 103 104 func TestNoticeErrorMessageSecurityPolicy(t *testing.T) { 105 replyfn := func(reply *internal.ConnectReply) { reply.SecurityPolicies.AllowRawExceptionMessages.SetEnabled(false) } 106 app := testApp(replyfn, nil, t) 107 txn := app.StartTransaction("hello", nil, nil) 108 err := txn.NoticeError(myError{}) 109 if nil != err { 110 t.Error(err) 111 } 112 txn.End() 113 app.ExpectErrors(t, []internal.WantError{{ 114 TxnName: "OtherTransaction/Go/hello", 115 Msg: securityPolicyErrorMsg, 116 Klass: "newrelic.myError", 117 Caller: "go-agent.TestNoticeErrorMessageSecurityPolicy", 118 }}) 119 app.ExpectErrorEvents(t, []internal.WantEvent{{ 120 Intrinsics: map[string]interface{}{ 121 "error.class": "newrelic.myError", 122 "error.message": securityPolicyErrorMsg, 123 "transactionName": "OtherTransaction/Go/hello", 124 }, 125 }}) 126 app.ExpectMetrics(t, backgroundErrorMetrics) 127 } 128 129 func TestNoticeErrorLocallyDisabled(t *testing.T) { 130 cfgFn := func(cfg *Config) { cfg.ErrorCollector.Enabled = false } 131 app := testApp(nil, cfgFn, t) 132 txn := app.StartTransaction("hello", nil, nil) 133 err := txn.NoticeError(myError{}) 134 if errorsLocallyDisabled != err { 135 t.Error(err) 136 } 137 txn.End() 138 app.ExpectErrors(t, []internal.WantError{}) 139 app.ExpectErrorEvents(t, []internal.WantEvent{}) 140 app.ExpectMetrics(t, backgroundMetrics) 141 } 142 143 func TestNoticeErrorRemotelyDisabled(t *testing.T) { 144 replyfn := func(reply *internal.ConnectReply) { reply.CollectErrors = false } 145 app := testApp(replyfn, nil, t) 146 txn := app.StartTransaction("hello", nil, nil) 147 err := txn.NoticeError(myError{}) 148 if errorsRemotelyDisabled != err { 149 t.Error(err) 150 } 151 txn.End() 152 app.ExpectErrors(t, []internal.WantError{}) 153 app.ExpectErrorEvents(t, []internal.WantEvent{}) 154 app.ExpectMetrics(t, backgroundMetrics) 155 } 156 157 func TestNoticeErrorNil(t *testing.T) { 158 app := testApp(nil, nil, t) 159 txn := app.StartTransaction("hello", nil, nil) 160 err := txn.NoticeError(nil) 161 if errNilError != err { 162 t.Error(err) 163 } 164 txn.End() 165 app.ExpectErrors(t, []internal.WantError{}) 166 app.ExpectErrorEvents(t, []internal.WantEvent{}) 167 app.ExpectMetrics(t, backgroundMetrics) 168 } 169 170 func TestNoticeErrorEventsLocallyDisabled(t *testing.T) { 171 cfgFn := func(cfg *Config) { cfg.ErrorCollector.CaptureEvents = false } 172 app := testApp(nil, cfgFn, t) 173 txn := app.StartTransaction("hello", nil, nil) 174 err := txn.NoticeError(myError{}) 175 if nil != err { 176 t.Error(err) 177 } 178 txn.End() 179 app.ExpectErrors(t, []internal.WantError{{ 180 TxnName: "OtherTransaction/Go/hello", 181 Msg: "my msg", 182 Klass: "newrelic.myError", 183 Caller: "go-agent.TestNoticeErrorEventsLocallyDisabled", 184 }}) 185 app.ExpectErrorEvents(t, []internal.WantEvent{}) 186 app.ExpectMetrics(t, backgroundErrorMetrics) 187 } 188 189 func TestNoticeErrorEventsRemotelyDisabled(t *testing.T) { 190 replyfn := func(reply *internal.ConnectReply) { reply.CollectErrorEvents = false } 191 app := testApp(replyfn, nil, t) 192 txn := app.StartTransaction("hello", nil, nil) 193 err := txn.NoticeError(myError{}) 194 if nil != err { 195 t.Error(err) 196 } 197 txn.End() 198 app.ExpectErrors(t, []internal.WantError{{ 199 TxnName: "OtherTransaction/Go/hello", 200 Msg: "my msg", 201 Klass: "newrelic.myError", 202 Caller: "go-agent.TestNoticeErrorEventsRemotelyDisabled", 203 }}) 204 app.ExpectErrorEvents(t, []internal.WantEvent{}) 205 app.ExpectMetrics(t, backgroundErrorMetrics) 206 } 207 208 type errorWithClass struct{ class string } 209 210 func (e errorWithClass) Error() string { return "my msg" } 211 func (e errorWithClass) ErrorClass() string { return e.class } 212 213 func TestErrorWithClasser(t *testing.T) { 214 app := testApp(nil, nil, t) 215 txn := app.StartTransaction("hello", nil, nil) 216 err := txn.NoticeError(errorWithClass{class: "zap"}) 217 if nil != err { 218 t.Error(err) 219 } 220 txn.End() 221 app.ExpectErrors(t, []internal.WantError{{ 222 TxnName: "OtherTransaction/Go/hello", 223 Msg: "my msg", 224 Klass: "zap", 225 Caller: "go-agent.TestErrorWithClasser", 226 URL: "", 227 }}) 228 app.ExpectErrorEvents(t, []internal.WantEvent{{ 229 Intrinsics: map[string]interface{}{ 230 "error.class": "zap", 231 "error.message": "my msg", 232 "transactionName": "OtherTransaction/Go/hello", 233 }, 234 }}) 235 app.ExpectMetrics(t, backgroundErrorMetrics) 236 } 237 238 func TestErrorWithClasserReturnsEmpty(t *testing.T) { 239 app := testApp(nil, nil, t) 240 txn := app.StartTransaction("hello", nil, nil) 241 err := txn.NoticeError(errorWithClass{class: ""}) 242 if nil != err { 243 t.Error(err) 244 } 245 txn.End() 246 app.ExpectErrors(t, []internal.WantError{{ 247 TxnName: "OtherTransaction/Go/hello", 248 Msg: "my msg", 249 Klass: "newrelic.errorWithClass", 250 Caller: "go-agent.TestErrorWithClasserReturnsEmpty", 251 URL: "", 252 }}) 253 app.ExpectErrorEvents(t, []internal.WantEvent{{ 254 Intrinsics: map[string]interface{}{ 255 "error.class": "newrelic.errorWithClass", 256 "error.message": "my msg", 257 "transactionName": "OtherTransaction/Go/hello", 258 }, 259 }}) 260 app.ExpectMetrics(t, backgroundErrorMetrics) 261 } 262 263 type withStackTrace struct{ trace []uintptr } 264 265 func makeErrorWithStackTrace() error { 266 callers := make([]uintptr, 20) 267 written := runtime.Callers(1, callers) 268 return withStackTrace{ 269 trace: callers[0:written], 270 } 271 } 272 273 func (e withStackTrace) Error() string { return "my msg" } 274 func (e withStackTrace) StackTrace() []uintptr { return e.trace } 275 276 func TestErrorWithStackTrace(t *testing.T) { 277 app := testApp(nil, nil, t) 278 txn := app.StartTransaction("hello", nil, nil) 279 e := makeErrorWithStackTrace() 280 err := txn.NoticeError(e) 281 if nil != err { 282 t.Error(err) 283 } 284 txn.End() 285 app.ExpectErrors(t, []internal.WantError{{ 286 TxnName: "OtherTransaction/Go/hello", 287 Msg: "my msg", 288 Klass: "newrelic.withStackTrace", 289 Caller: "go-agent.makeErrorWithStackTrace", 290 URL: "", 291 }}) 292 app.ExpectErrorEvents(t, []internal.WantEvent{{ 293 Intrinsics: map[string]interface{}{ 294 "error.class": "newrelic.withStackTrace", 295 "error.message": "my msg", 296 "transactionName": "OtherTransaction/Go/hello", 297 }, 298 }}) 299 app.ExpectMetrics(t, backgroundErrorMetrics) 300 } 301 302 func TestErrorWithStackTraceReturnsNil(t *testing.T) { 303 app := testApp(nil, nil, t) 304 txn := app.StartTransaction("hello", nil, nil) 305 e := withStackTrace{trace: nil} 306 err := txn.NoticeError(e) 307 if nil != err { 308 t.Error(err) 309 } 310 txn.End() 311 app.ExpectErrors(t, []internal.WantError{{ 312 TxnName: "OtherTransaction/Go/hello", 313 Msg: "my msg", 314 Klass: "newrelic.withStackTrace", 315 Caller: "go-agent.TestErrorWithStackTraceReturnsNil", 316 URL: "", 317 }}) 318 app.ExpectErrorEvents(t, []internal.WantEvent{{ 319 Intrinsics: map[string]interface{}{ 320 "error.class": "newrelic.withStackTrace", 321 "error.message": "my msg", 322 "transactionName": "OtherTransaction/Go/hello", 323 }, 324 }}) 325 app.ExpectMetrics(t, backgroundErrorMetrics) 326 } 327 328 func TestNewrelicErrorNoAttributes(t *testing.T) { 329 app := testApp(nil, nil, t) 330 txn := app.StartTransaction("hello", nil, nil) 331 err := txn.NoticeError(Error{ 332 Message: "my msg", 333 Class: "my class", 334 }) 335 if nil != err { 336 t.Error(err) 337 } 338 txn.End() 339 app.ExpectErrors(t, []internal.WantError{{ 340 TxnName: "OtherTransaction/Go/hello", 341 Msg: "my msg", 342 Klass: "my class", 343 Caller: "go-agent.TestNewrelicErrorNoAttributes", 344 URL: "", 345 }}) 346 app.ExpectErrorEvents(t, []internal.WantEvent{{ 347 Intrinsics: map[string]interface{}{ 348 "error.class": "my class", 349 "error.message": "my msg", 350 "transactionName": "OtherTransaction/Go/hello", 351 }, 352 }}) 353 app.ExpectMetrics(t, backgroundErrorMetrics) 354 } 355 356 func TestNewrelicErrorValidAttributes(t *testing.T) { 357 extraAttributes := map[string]interface{}{ 358 "zip": "zap", 359 } 360 app := testApp(nil, nil, t) 361 txn := app.StartTransaction("hello", nil, nil) 362 err := txn.NoticeError(Error{ 363 Message: "my msg", 364 Class: "my class", 365 Attributes: extraAttributes, 366 }) 367 if nil != err { 368 t.Error(err) 369 } 370 txn.End() 371 app.ExpectErrors(t, []internal.WantError{{ 372 TxnName: "OtherTransaction/Go/hello", 373 Msg: "my msg", 374 Klass: "my class", 375 Caller: "go-agent.TestNewrelicErrorValidAttributes", 376 URL: "", 377 UserAttributes: extraAttributes, 378 }}) 379 app.ExpectErrorEvents(t, []internal.WantEvent{{ 380 Intrinsics: map[string]interface{}{ 381 "error.class": "my class", 382 "error.message": "my msg", 383 "transactionName": "OtherTransaction/Go/hello", 384 }, 385 UserAttributes: extraAttributes, 386 }}) 387 app.ExpectMetrics(t, backgroundErrorMetrics) 388 } 389 390 func TestNewrelicErrorAttributesHighSecurity(t *testing.T) { 391 extraAttributes := map[string]interface{}{ 392 "zip": "zap", 393 } 394 cfgFn := func(cfg *Config) { cfg.HighSecurity = true } 395 app := testApp(nil, cfgFn, t) 396 txn := app.StartTransaction("hello", nil, nil) 397 err := txn.NoticeError(Error{ 398 Message: "my msg", 399 Class: "my class", 400 Attributes: extraAttributes, 401 }) 402 if nil != err { 403 t.Error(err) 404 } 405 txn.End() 406 app.ExpectErrors(t, []internal.WantError{{ 407 TxnName: "OtherTransaction/Go/hello", 408 Msg: "message removed by high security setting", 409 Klass: "my class", 410 Caller: "go-agent.TestNewrelicErrorAttributesHighSecurity", 411 URL: "", 412 UserAttributes: map[string]interface{}{}, 413 }}) 414 app.ExpectErrorEvents(t, []internal.WantEvent{{ 415 Intrinsics: map[string]interface{}{ 416 "error.class": "my class", 417 "error.message": "message removed by high security setting", 418 "transactionName": "OtherTransaction/Go/hello", 419 }, 420 UserAttributes: map[string]interface{}{}, 421 }}) 422 app.ExpectMetrics(t, backgroundErrorMetrics) 423 } 424 425 func TestNewrelicErrorAttributesSecurityPolicy(t *testing.T) { 426 extraAttributes := map[string]interface{}{ 427 "zip": "zap", 428 } 429 replyfn := func(reply *internal.ConnectReply) { reply.SecurityPolicies.CustomParameters.SetEnabled(false) } 430 app := testApp(replyfn, nil, t) 431 txn := app.StartTransaction("hello", nil, nil) 432 err := txn.NoticeError(Error{ 433 Message: "my msg", 434 Class: "my class", 435 Attributes: extraAttributes, 436 }) 437 if nil != err { 438 t.Error(err) 439 } 440 txn.End() 441 app.ExpectErrors(t, []internal.WantError{{ 442 TxnName: "OtherTransaction/Go/hello", 443 Msg: "my msg", 444 Klass: "my class", 445 Caller: "go-agent.TestNewrelicErrorAttributesSecurityPolicy", 446 URL: "", 447 UserAttributes: map[string]interface{}{}, 448 }}) 449 app.ExpectErrorEvents(t, []internal.WantEvent{{ 450 Intrinsics: map[string]interface{}{ 451 "error.class": "my class", 452 "error.message": "my msg", 453 "transactionName": "OtherTransaction/Go/hello", 454 }, 455 UserAttributes: map[string]interface{}{}, 456 }}) 457 app.ExpectMetrics(t, backgroundErrorMetrics) 458 } 459 460 func TestNewrelicErrorAttributeOverridesNormalAttribute(t *testing.T) { 461 extraAttributes := map[string]interface{}{ 462 "zip": "zap", 463 } 464 app := testApp(nil, nil, t) 465 txn := app.StartTransaction("hello", nil, nil) 466 if err := txn.AddAttribute("zip", 123); nil != err { 467 t.Error(err) 468 } 469 err := txn.NoticeError(Error{ 470 Message: "my msg", 471 Class: "my class", 472 Attributes: extraAttributes, 473 }) 474 if nil != err { 475 t.Error(err) 476 } 477 txn.End() 478 app.ExpectErrors(t, []internal.WantError{{ 479 TxnName: "OtherTransaction/Go/hello", 480 Msg: "my msg", 481 Klass: "my class", 482 Caller: "go-agent.TestNewrelicErrorAttributeOverridesNormalAttribute", 483 URL: "", 484 UserAttributes: extraAttributes, 485 }}) 486 app.ExpectErrorEvents(t, []internal.WantEvent{{ 487 Intrinsics: map[string]interface{}{ 488 "error.class": "my class", 489 "error.message": "my msg", 490 "transactionName": "OtherTransaction/Go/hello", 491 }, 492 UserAttributes: extraAttributes, 493 }}) 494 app.ExpectMetrics(t, backgroundErrorMetrics) 495 } 496 497 func TestNewrelicErrorInvalidAttributes(t *testing.T) { 498 extraAttributes := map[string]interface{}{ 499 "zip": "zap", 500 "INVALID": struct{}{}, 501 } 502 app := testApp(nil, nil, t) 503 txn := app.StartTransaction("hello", nil, nil) 504 err := txn.NoticeError(Error{ 505 Message: "my msg", 506 Class: "my class", 507 Attributes: extraAttributes, 508 }) 509 if _, ok := err.(internal.ErrInvalidAttributeType); !ok { 510 t.Error(err) 511 } 512 txn.End() 513 app.ExpectErrors(t, []internal.WantError{}) 514 app.ExpectErrorEvents(t, []internal.WantEvent{}) 515 app.ExpectMetrics(t, backgroundMetrics) 516 } 517 518 func TestExtraErrorAttributeRemovedThroughConfiguration(t *testing.T) { 519 cfgfn := func(cfg *Config) { 520 cfg.ErrorCollector.Attributes.Exclude = []string{"IGNORE_ME"} 521 } 522 app := testApp(nil, cfgfn, t) 523 txn := app.StartTransaction("hello", nil, nil) 524 err := txn.NoticeError(Error{ 525 Message: "my msg", 526 Class: "my class", 527 Attributes: map[string]interface{}{ 528 "zip": "zap", 529 "IGNORE_ME": 123, 530 }, 531 }) 532 if nil != err { 533 t.Error(err) 534 } 535 txn.End() 536 app.ExpectErrors(t, []internal.WantError{{ 537 TxnName: "OtherTransaction/Go/hello", 538 Msg: "my msg", 539 Klass: "my class", 540 Caller: "go-agent.TestExtraErrorAttributeRemovedThroughConfiguration", 541 URL: "", 542 UserAttributes: map[string]interface{}{"zip": "zap"}, 543 }}) 544 app.ExpectErrorEvents(t, []internal.WantEvent{{ 545 Intrinsics: map[string]interface{}{ 546 "error.class": "my class", 547 "error.message": "my msg", 548 "transactionName": "OtherTransaction/Go/hello", 549 }, 550 UserAttributes: map[string]interface{}{"zip": "zap"}, 551 }}) 552 app.ExpectMetrics(t, backgroundErrorMetrics) 553 554 } 555 556 func TestTooManyExtraErrorAttributes(t *testing.T) { 557 attrs := make(map[string]interface{}) 558 for i := 0; i <= internal.AttributeErrorLimit; i++ { 559 attrs[strconv.Itoa(i)] = i 560 } 561 app := testApp(nil, nil, t) 562 txn := app.StartTransaction("hello", nil, nil) 563 err := txn.NoticeError(Error{ 564 Message: "my msg", 565 Class: "my class", 566 Attributes: attrs, 567 }) 568 if errTooManyErrorAttributes != err { 569 t.Error(err) 570 } 571 txn.End() 572 app.ExpectErrors(t, []internal.WantError{}) 573 app.ExpectErrorEvents(t, []internal.WantEvent{}) 574 app.ExpectMetrics(t, backgroundMetrics) 575 }