Tarantool development patches archive
 help / color / mirror / Atom feed
From: Leonid Vasiliev <lvasiliev@tarantool.org>
To: v.shpilevoy@tarantool.org
Cc: tarantool-patches@dev.tarantool.org
Subject: [Tarantool-patches] [PATCH] error: add format string usage to form a CustomError message
Date: Thu, 28 May 2020 11:31:01 +0300	[thread overview]
Message-ID: <db428fc6199eab0f08782b90efa6cef13fa1d812.1590654490.git.lvasiliev@tarantool.org> (raw)

For the CustomError the ability to create a message
using a format string was added.

Closes #4903

@TarantoolBot document
Title: Add format string usage to form a CustomError message
When creating a ClientError error the predefined format
(corresponding with the error code) is used.
When creating a CustomError error a format string can be
used to form the message.

ClientError:
```Lua
box.error(code, reason args)
```

CustomError:
```Lua
box.error(type, reason format string, reason args)
```
---
https://github.com/tarantool/tarantool/issues/4903
https://github.com/tarantool/tarantool/tree/lvasiliev/gh-4903-format-string-for-CustomError
@ChangeLog Add format string usage to form a CustomError message

 src/box/lua/error.cc    | 33 +++++++++++++++++++++++----------
 test/box/error.result   | 10 ++++++++++
 test/box/error.test.lua |  5 +++++
 3 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc
index e0a3e73..54ec284 100644
--- a/src/box/lua/error.cc
+++ b/src/box/lua/error.cc
@@ -43,15 +43,18 @@ extern "C" {
 #include "box/error.h"
 
 /**
- * Parse Lua arguments (they can come as single table
- * f({code : number, reason : string}) or as separate members
- * f(code, reason)) and construct struct error with given values.
+ * Parse Lua arguments (they can come as single table or as
+ * separate members) and construct struct error with given values.
  *
- * Instead of 'code' it is possible to specify a string name of
- * the error object's type:
+ * Can be used either the 'code' (numeric) for create a ClientError
+ * error with corresponding message (the format is predefined)
+ * and type or the 'type' (string) for create a CustomError error
+ * with custom type and desired message.
  *
- *     box.error(type, reason, ...)
- *     box.error({type = string, reason = string, ...})
+ *     box.error(code, reason args)
+ *     box.error({code = num, reason = string, ...})
+ *     box.error(type, reason format string, reason args)
+ *     box.error({type = string, code = num, reason = string, ...})
  *
  * In case one of arguments is missing its corresponding field
  * in struct error is filled with default value.
@@ -69,12 +72,21 @@ luaT_error_create(lua_State *L, int top_base)
 	int top_type = lua_type(L, top_base);
 	if (top >= top_base && (top_type == LUA_TNUMBER ||
 				top_type == LUA_TSTRING)) {
+		/* Shift of the "reason args". */
+		int shift = 1;
 		if (top_type == LUA_TNUMBER) {
 			code = lua_tonumber(L, top_base);
 			reason = tnt_errcode_desc(code);
 		} else {
 			custom_type = lua_tostring(L, top_base);
-			reason = "%s";
+			/*
+			 * For the CustomError, the message format
+			 * must be set via a function argument.
+			 */
+			if (lua_type(L, top_base + 1) != LUA_TSTRING)
+				return NULL;
+			reason = lua_tostring(L, top_base + 1);
+			shift = 2;
 		}
 		if (top > top_base) {
 			/* Call string.format(reason, ...) to format message */
@@ -85,9 +97,10 @@ luaT_error_create(lua_State *L, int top_base)
 			if (lua_isnil(L, -1))
 				goto raise;
 			lua_pushstring(L, reason);
-			for (int i = top_base + 1; i <= top; i++)
+			int nargs = 1;
+			for (int i = top_base + shift; i <= top; ++i, ++nargs)
 				lua_pushvalue(L, i);
-			lua_call(L, top - top_base + 1, 1);
+			lua_call(L, nargs, 1);
 			reason = lua_tostring(L, -1);
 		} else if (strchr(reason, '%') != NULL) {
 			/* Missing arguments to format string */
diff --git a/test/box/error.result b/test/box/error.result
index 59a5301..2196fa5 100644
--- a/test/box/error.result
+++ b/test/box/error.result
@@ -956,3 +956,13 @@ s:drop()
 box.schema.func.drop('runtimeerror')
  | ---
  | ...
+
+-- gh-4903: add format string usage for a CustomError message
+--
+err = box.error.new('TestType', 'Message arg1: %s. Message arg2: %u', '1', 2)
+ | ---
+ | ...
+err.message
+ | ---
+ | - 'Message arg1: 1. Message arg2: 2'
+ | ...
diff --git a/test/box/error.test.lua b/test/box/error.test.lua
index d63e835..ed95d1d 100644
--- a/test/box/error.test.lua
+++ b/test/box/error.test.lua
@@ -270,3 +270,8 @@ gc_err
 
 s:drop()
 box.schema.func.drop('runtimeerror')
+
+-- gh-4903: add format string usage for a CustomError message
+--
+err = box.error.new('TestType', 'Message arg1: %s. Message arg2: %u', '1', 2)
+err.message
-- 
2.7.4

             reply	other threads:[~2020-05-28  8:31 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-28  8:31 Leonid Vasiliev [this message]
2020-05-29 22:05 ` Vladislav Shpilevoy
2020-06-01 12:54   ` Leonid Vasiliev
2020-06-01 13:47     ` Vladislav Shpilevoy
2020-06-02 14:22 ` Kirill Yukhin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=db428fc6199eab0f08782b90efa6cef13fa1d812.1590654490.git.lvasiliev@tarantool.org \
    --to=lvasiliev@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH] error: add format string usage to form a CustomError message' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox