diff --git a/CHANGELOG.md b/CHANGELOG.md index d196361..8e1f676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 2.5.1 (2024-10-21) + +### Bug fixes + +* Move start of delivery goroutine to configure, don't wait on signals in delivery + [#250](https://github.com/bugsnag/bugsnag-go/pull/250) + ## 2.5.0 (2024-08-27) ### Enhancements diff --git a/Gemfile b/Gemfile index e20e035..12edf99 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source 'https://rubygems.org' -gem "bugsnag-maze-runner", "~> 9.0" \ No newline at end of file +gem "bugsnag-maze-runner", "~> 9.14" \ No newline at end of file diff --git a/features/net-http/appversion.feature b/features/net-http/appversion.feature index c2d10ad..95f3c52 100644 --- a/features/net-http/appversion.feature +++ b/features/net-http/appversion.feature @@ -11,7 +11,6 @@ Scenario: A error report contains the configured app type when using a net http And I open the URL "http://localhost:4512/handled" And I wait to receive an error And I should receive no sessions - And the error is valid for the error reporting API version "4" for the "Bugsnag Go" notifier And the event "app.version" equals "3.1.2" Scenario: A session report contains the configured app type when using a net http app @@ -21,5 +20,4 @@ Scenario: A session report contains the configured app type when using a net htt And I wait for the host "localhost" to open port "4512" And I open the URL "http://localhost:4512/session" And I wait to receive a session - And the session is valid for the session reporting API version "1.0" for the "Bugsnag Go" notifier And the session payload field "app.version" equals "3.1.2" diff --git a/features/sessioncontext.feature b/features/sessioncontext.feature index 8cc09a1..a3af0b6 100644 --- a/features/sessioncontext.feature +++ b/features/sessioncontext.feature @@ -6,8 +6,5 @@ Scenario: An error report contains a session count when part of a session Then I wait to receive 1 error # one session is created on start And I wait to receive 2 session - And the error is valid for the error reporting API version "4" for the "Bugsnag Go" notifier - And the session is valid for the session reporting API version "1.0" for the "Bugsnag Go" notifier And I discard the oldest session - And the session is valid for the session reporting API version "1.0" for the "Bugsnag Go" notifier And the session payload has a valid sessions array \ No newline at end of file diff --git a/features/support/env.rb b/features/support/env.rb index d806b18..3235071 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -5,4 +5,25 @@ steps %( When I configure the base endpoint ) -end \ No newline at end of file +end + +Maze.config.add_validator('error') do |validator| + validator.validate_header('bugsnag-api-key') { |value| value.eql?($api_key) } + validator.validate_header('content-type') { |value| value.eql?('application/json') } + validator.validate_header('bugsnag-payload-version') { |value| value.eql?('4') } + validator.validate_header('bugsnag-sent-at') { |value| Date.iso8601(value) } + + validator.element_has_value('notifier.name', 'Bugsnag Go') + validator.each_element_exists(['notifier.url', 'notifier.version', 'events']) + validator.each_event_contains_each(['severity', 'severityReason.type', 'unhandled', 'exceptions']) +end + +Maze.config.add_validator('session') do |validator| + validator.validate_header('bugsnag-api-key') { |value| value.eql?($api_key) } + validator.validate_header('content-type') { |value| value.eql?('application/json') } + validator.validate_header('bugsnag-payload-version') { |value| value.eql?('1.0') } + validator.validate_header('bugsnag-sent-at') { |value| Date.iso8601(value) } + + validator.element_has_value('notifier.name', 'Bugsnag Go') + validator.each_element_exists(['notifier.url', 'notifier.version', 'app', 'device']) +end diff --git a/v2/bugsnag.go b/v2/bugsnag.go index 66a5895..05d2778 100644 --- a/v2/bugsnag.go +++ b/v2/bugsnag.go @@ -21,7 +21,7 @@ import ( ) // Version defines the version of this Bugsnag notifier -const Version = "2.5.0" +const Version = "2.5.1" var panicHandlerOnce sync.Once var sessionTrackerOnce sync.Once @@ -48,6 +48,9 @@ func Configure(config Configuration) { readEnvConfigOnce.Do(Config.loadEnv) Config.update(&config) updateSessionConfig() + + // start delivery goroutine later than the module import time + go publisher.delivery() // Only do once in case the user overrides the default panichandler, and // configures multiple times. panicHandlerOnce.Do(Config.PanicHandler) diff --git a/v2/bugsnag_test.go b/v2/bugsnag_test.go index da72f3b..e31cbd9 100644 --- a/v2/bugsnag_test.go +++ b/v2/bugsnag_test.go @@ -151,6 +151,9 @@ func (tp *testPublisher) publishReport(p *payload) error { func (tp *testPublisher) setMainProgramContext(context.Context) { } +func (tp *testPublisher) delivery() { +} + func TestNotifySyncThenAsync(t *testing.T) { ts, _ := setup() defer ts.Close() diff --git a/v2/report_publisher.go b/v2/report_publisher.go index 6ccb17e..43937e1 100644 --- a/v2/report_publisher.go +++ b/v2/report_publisher.go @@ -3,26 +3,18 @@ package bugsnag import ( "context" "fmt" - "os" - "os/signal" - "syscall" ) type reportPublisher interface { publishReport(*payload) error setMainProgramContext(context.Context) + delivery() } func (defPub *defaultReportPublisher) delivery() { - signalsCh := make(chan os.Signal, 1) - signal.Notify(signalsCh, syscall.SIGINT, syscall.SIGTERM) - waitForEnd: for { select { - case <-signalsCh: - defPub.isClosing = true - break waitForEnd case <-defPub.mainProgramCtx.Done(): defPub.isClosing = true break waitForEnd @@ -42,10 +34,10 @@ waitForEnd: // Send remaining elements from the queue close(defPub.eventsChan) for p := range defPub.eventsChan { - if err := p.deliver(); err != nil { - // Ensure that any errors are logged if they occur in a goroutine. - p.logf("bugsnag/defaultReportPublisher.publishReport: %v", err) - } + if err := p.deliver(); err != nil { + // Ensure that any errors are logged if they occur in a goroutine. + p.logf("bugsnag/defaultReportPublisher.publishReport: %v", err) + } } } @@ -59,8 +51,6 @@ func newPublisher() reportPublisher { defPub := defaultReportPublisher{isClosing: false, mainProgramCtx: context.TODO()} defPub.eventsChan = make(chan *payload, 100) - go defPub.delivery() - return &defPub }