Uploaded image for project: 'MariaDB Connector/node.js'
  1. MariaDB Connector/node.js
  2. CONJS-329

Exception handler not deactivated after .prepare() or .execute() finishes

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 3.4.5
    • None
    • None
    • None

    Description

      In the process of replacing the "mysql2" NodeJS connector with the "mariadb" one (which is advertised as being a - nearly - "drop-in" substitution for the former) we stumbled onto unexpected (and to the best of our knowledge, undocumented) behaviour that we want to report here.

      It should be noted that:

      • We use (and therefore observed this issue) with the callback interface only (we have not tested the other available ones as we don't need them).
      • We use a tiny (custom) wrapper around the various database drivers we use in order to unify their workflows; part of this is that we separately call the .prepare() method from the driver first, cache the statement handler in our wrapper and then call .execute() on it as many times as we need (we'll explain below why this matters for the "mariadb" driver).
      • We use stand-alone single connections without the pool feature.

      After we switched to the "mariadb" driver, we noticed that an exception, produced somewhere in the callback stack, would no longer bubble up (until it gets caught by our top-level catcher), but will instead result in a callback, previously passed to the .prepare() or .execute() method of the "mariadb" driver, being triggered - even if the error has nothing to do with the SQL connection and does not result from a query. In other words, we observed that the "mariadb" driver installs an exception catcher every time the .prepare() or .execute() method is invoked - and this catcher does not get inactivated (e.g., via some per-connection switch) after the .prepare() or .execute() method is done (i.e. the callback from this method has been invoked without an error). We find this behaviour quite unusual and wrong, because it inhibits the normal exception propagation in a very opaque way.

      We attach here a simple POC script. It connects to the DB, runs the .prepare() method and then .execute() method on the received statement handler. At the top level, we declare two empty objects "a" and "b"; after the .prepare() method has successfully completed, we try to read the value of a non-existing property of the "a" object (to generate an exception); we do the same with the "b" object after the .execute() method has completed successfully. As this simple POC has no global exception catcher, the expected behaviour in both cases is to have the exception bubble up to the top level, terminate the script and dump a stack trace. With the "mariadb" driver, however, the callback from the .prepare() or .execute() method is invoked instead and it logs an appropriate message.

      We managed to trace the reason for this misbehaviour down to two functions in the "mariadb" driver's code; commenting out the .catch() method on them successfully fixes the problem for us. We cannot claim that this is the best possible way to resolve the issue, as we have little knowledge of the inner workings of he "mariadb" driver - but it can hint developers on what would be the proper way of dealing with the issue. We attach a diff to illustrate the problematic places.

      On a final note, we noticed that calling the .execute() method on the connection (and not on the statement handler) does not experience this issue; apparently, the "mariadb" driver still runs the prepare step and then separately the execute step, but uses different programme code (why?). We do not deem this a resolution to the problem, however, because this way we lose the ability to invoke the same prepared statement multiple times at will – but also because the prepare + execute should simply always work (without any internal statement caching trickery).

      Attachments

        1. _poc.js
          1 kB
          Assen Totin
        2. mariadb.diff
          1 kB
          Assen Totin

        Activity

          People

            diego dupin Diego Dupin
            Totin Assen Totin
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.