Skip to content

Always emit request aborted event #1534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 24, 2021
Merged

Always emit request aborted event #1534

merged 4 commits into from
Aug 24, 2021

Conversation

delvedor
Copy link
Member

If the client is busy running an async operation, the .abort() call might be executed before sending the actual request. In such case, the error was swallowed, now it will always be emitted, either in the request or response event.

Closes: #1517

@trentm
Copy link
Member

trentm commented Aug 23, 2021

This works for me with the node.js APM agent, where "works" here is that the APM instrumentation of @elastic/elasticsearch will notice and capture an APM "error" event for this RequestAbortedError.

The mechanism is slightly different than described in #1517, because the RequestAbortedError is now being captured in the "request" event rather than the "response" event... which makes sense because the POST /_search request isn't even started when the req.abort() happens during the productCheck.

test notes

I installed this feature branch:

npm install github:elastic/elasticsearch-js#fix-1517

My apm-using test script that will start a transaction and make a client.search() call:

const apm = require('./').start({
  captureExceptions: false,
  logUncaughtExceptions: true,
  captureSpanStackTraces: false,
  stackTraceLimit: 3,
  apiRequestTime: 3,
  metricsInterval: 0,
  cloudProvider: 'none',
  centralConfig: false,
  // ^^ Boilerplate config above this line is to focus on just tracing.
  serviceName: 'esfoo'
})

const { Client } = require('@elastic/elasticsearch')
var client = new Client({
  node: 'http://localhost:9200',
  auth: { username: 'admin', password: 'changeme' }
})

client.on('response', function (err, event) {
  console.log('"response" event: err=', err && err.name)
})

apm.startTransaction('t0')
var req = client.search(
  { body: { size: 1 } },
  function (err, _result) {
    console.log('callback: err:', err && err.name)
    apm.endTransaction()
  }
)
setImmediate(function () {
  req.abort()
})

Running that:

% node esfoo.js
"response" event: err= null
callback: err: RequestAbortedError
{"log.level":"info","@timestamp":"2021-08-23T18:45:17.204Z","log":{"logger":"elastic-apm-node"},"ecs":{"version":"1.6.0"},"message":"Sending error to Elastic APM: {\"id\":\"759c2d784e4e716e8b98e00f080dd86f\"}"}

That captured error:

{
    "error": {
        "id": "759c2d784e4e716e8b98e00f080dd86f",
        "timestamp": 1629744317196000,
        "parent_id": "3fab07fbe0a7fe76",
        "trace_id": "e6e2fecf298ed8993795200f696c9556",
        "transaction_id": "71c41b9ecdbaca66",
        "transaction": {
            "type": null,
            "sampled": true
        },
        "context": {
            "user": {},
            "tags": {},
            "custom": {}
        },
        "exception": {
            "message": "Request aborted",
            "type": "RequestAbortedError",
            "handled": true,
            "attributes": {
                "name": "RequestAbortedError",
                "message": "Request aborted"
            },
            "module": "@elastic/elasticsearch",
            "stacktrace": [
                ...
            ]
        },
        "culprit": "makeRequest (node_modules/@elastic/elasticsearch/lib/Transport.js)"
    }
}

Copy link
Member

@trentm trentm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works with the node.js APM agent. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

client.on("response", ...) event does not include err=RequestAbortedError if aborted during productCheck()
2 participants