From 5deb8a2f7b3c5535b2574ea4fa7aba3a909e4a09 Mon Sep 17 00:00:00 2001 From: Reuben Morais Date: Sun, 3 May 2020 15:39:07 +0200 Subject: [PATCH 1/2] Don't leave partially initialized scorer on failure --- native_client/deepspeech.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/native_client/deepspeech.cc b/native_client/deepspeech.cc index 96989e04..b5b0f163 100644 --- a/native_client/deepspeech.cc +++ b/native_client/deepspeech.cc @@ -333,11 +333,12 @@ int DS_EnableExternalScorer(ModelState* aCtx, const char* aScorerPath) { - aCtx->scorer_.reset(new Scorer()); - int err = aCtx->scorer_->init(aScorerPath, aCtx->alphabet_); + std::unique_ptr scorer(new Scorer()); + int err = scorer->init(aScorerPath, aCtx->alphabet_); if (err != 0) { return DS_ERR_INVALID_SCORER; } + aCtx->scorer_ = std::move(scorer); return DS_ERR_OK; } From 48971413e524280f2b677013ae05389dc2115934 Mon Sep 17 00:00:00 2001 From: Reuben Morais Date: Sun, 3 May 2020 15:39:31 +0200 Subject: [PATCH 2/2] Improve EnableExternalScorer error handling in Python and JS bindings --- native_client/javascript/index.js | 11 +++++++---- native_client/python/__init__.py | 7 ++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/native_client/javascript/index.js b/native_client/javascript/index.js index 8fd8659c..7d742aad 100644 --- a/native_client/javascript/index.js +++ b/native_client/javascript/index.js @@ -35,7 +35,7 @@ function Model(aModelPath) { const status = rets[0]; const impl = rets[1]; if (status !== 0) { - throw "CreateModel failed "+binding.ErrorCodeToErrorMessage(status)+" 0x" + status.toString(16); + throw "CreateModel failed with '"+binding.ErrorCodeToErrorMessage(status)+"' (0x" + status.toString(16) + ")"; } this._impl = impl; @@ -76,10 +76,13 @@ Model.prototype.sampleRate = function() { * * @param {string} aScorerPath The path to the external scorer file. * - * @return {number} Zero on success, non-zero on failure (invalid arguments). + * @throws on error */ Model.prototype.enableExternalScorer = function(aScorerPath) { - return binding.EnableExternalScorer(this._impl, aScorerPath); + const status = binding.EnableExternalScorer(this._impl, aScorerPath); + if (status !== 0) { + throw "EnableExternalScorer failed with '"+binding.ErrorCodeToErrorMessage(status)+"' (0x" + status.toString(16) + ")"; + } } /** @@ -139,7 +142,7 @@ Model.prototype.createStream = function() { const status = rets[0]; const ctx = rets[1]; if (status !== 0) { - throw "CreateStream failed "+binding.ErrorCodeToErrorMessage(status)+" 0x" + status.toString(16); + throw "CreateStream failed with '"+binding.ErrorCodeToErrorMessage(status)+"' (0x" + status.toString(16) + ")"; } return new Stream(ctx); } diff --git a/native_client/python/__init__.py b/native_client/python/__init__.py index a6af56f1..8dec3f0c 100644 --- a/native_client/python/__init__.py +++ b/native_client/python/__init__.py @@ -81,10 +81,11 @@ class Model(object): :param scorer_path: The path to the external scorer file. :type scorer_path: str - :return: Zero on success, non-zero on failure. - :type: int + :throws: RuntimeError on error """ - return deepspeech.impl.EnableExternalScorer(self._impl, scorer_path) + status = deepspeech.impl.EnableExternalScorer(self._impl, scorer_path) + if status != 0: + raise RuntimeError("EnableExternalScorer failed with '{}' (0x{:X})".format(deepspeech.impl.ErrorCodeToErrorMessage(status),status)) def disableExternalScorer(self): """