What is the standard code to check for valid/existing id in database-backed view in web2py? - error-handling

In web2py, suppose I have the following url:
www.example.com/customer/view/1
Which is backed by a view() function in the customer controller and displays the customer with id of 1 from a database.
In the view function I want to handle the following error cases:
No argument is passed (/customer/view/) -> raise 404
A non-integer argument is passed (/customer/view/apple) -> raise 404
An integer argument is passed but does not exist in database (/customer/view/999999) -> raise 404
An application error occurs such as cannot connect to database -> raise 500 exception
What is the standard/canonical/correct way to handle these cases in the controller function in way that returns the proper HTTP error? It's such a common scenario that I'd like to do it in a correct and succinct way every time.
This almost works except it doesn't distinguish between id not valid/existing errors and any other errors:
def view():
try:
customer = db(db.customer.id==request.args(0, cast=int)).select()[0]
except:
raise HTTP(404, 'Cannot find that customer')
return dict(customer=customer)

def view():
id = request.args(0, cast=int, otherwise=lambda: None)
customer = db(db.customer.id == id).select().first()
if not customer:
raise HTTP(404, 'Cannot find that customer' if id
else 'Missing/invalid customer ID')
return dict(customer=customer)
If the cast fails in request.args(), by default it will raise its own HTTP(404), but you won't have control over the message. So, you can instead use the otherwise argument to return None in that case. The database query will then return None if the arg is missing or a non-integer, or if the customer is not found in the database.

Related

Is there a way I can access the attribute in an Attribute Error without parsing the string?

My python version is 3.6
I am trying to give a more helpful message on attribute errors in a CLI framework that I am building. I have the following code
print(cli_config.test_exension_config.input_menu)
Which produces the error AttributeError: 'CLIConfig' object has no attribute 'test_exension_config'
Perfect, however now I want to give a recommendation on the closest attribute match as the attributes are dynamically created from a yaml file.
test_extension:
input_menu: # "InputMenuConfig_instantiation_test"
var:
So the closest attribute match would be test_extension_config.
Below is me catching the error and about to give a recommendation.
def __getattribute__(self, name) -> Any:
try:
return super().__getattribute__(name)
except AttributeError as ae:
# chance to handle the attribute differently
attr = get_erroring_attr(ae)
closest_match = next(get_close_matches(attr, list(vars(self).keys())))
if closest_match: # probably will have some threshold based on 'edit distance'
return closest_match
# if not, re-raise the exception
raise ae
I am wanting to just receive the attribute
I can parse the args of AttributeError but I wanted to know if there was another way to access the actual attribute name that is erroring without parsing the message.
In other words, in the last code block I have a method get_erroring_attr(ae) that takes in the AttributeError.
What would be the cleanest definition of def get_erroring_attr(ae) that will return the erroring attribute?
UPDATE:
So I did this and it works. I would just like to remove parsing as much as possible.
def __getattribute__(self, name) -> Any:
try:
return super().__getattribute__(name)
except AttributeError as ae:
# chance to handle the attribute differently
attr = self.get_erroring_attr(ae)
closest_match = next(match for match in get_close_matches(attr, list(vars(self).keys())))
if closest_match: # probably will have some threshold based on 'edit distance'
traceback.print_exc()
print(CLIColors.build_error_string(f"ERROR: Did you mean {CLIColors.build_value_string(closest_match)}?"))
sys.exit()
# if not, re-raise the exception
raise ae
def get_erroring_attr(self, attr_error: AttributeError):
message = attr_error.args[0]
_, error_attr_name = self.parse_attr_error_message(message)
return error_attr_name
def parse_attr_error_message(self, attr_err_msg: str):
parsed_msg = re.findall("'([^']*)'", attr_err_msg)
return parsed_msg
Which produces

If response contains the word 'any' then match response contains is failing

Let's say if I am having a scenario like
Scenario: Call a Get API and validate the response
Given path 'myteam'
When method get
Then status 201
And print response
And match response contains { teamFeature: 'pick any feature'}
And my API response is
{
"id": "6c0377cd-96c9-4651-bcc8-0c9a7d962bc3",
"teamFeature": "pick any feature"
}
Then I am getting the error like
example.feature:19 - javascript evaluation failed: feature'}, :1:9 Missing close quote
feature'}
^ in at line number 1 at column number 9
If my API response does not contain the word 'any' and I change the match statement then it is working fine. Looks like I need to escape the the word 'any' somehow.
May I know how can I escape the word 'any'?
Not sure if this is a bug in Karate.
Tried to call
com.intuit.karate.Match match = new com.intuit.karate.Match("pick any feature");
System.out.println(match.contains("pick any feature"));
And received following error
Exception in thread "main" java.lang.RuntimeException: javascript
evaluation failed: pick any feature, :1:5 Expected ; but found
any pick any feature
^ in at line number 1 at column number 5 at com.intuit.karate.ScriptBindings.eval(ScriptBindings.java:152) at
com.intuit.karate.ScriptBindings.updateBindingsAndEval(ScriptBindings.java:142)
at
com.intuit.karate.ScriptBindings.evalInNashorn(ScriptBindings.java:127)
at com.intuit.karate.Script.evalJsExpression(Script.java:423) at
com.intuit.karate.Script.evalKarateExpression(Script.java:337) at
com.intuit.karate.Script.evalKarateExpression(Script.java:203) at
com.intuit.karate.Match.(Match.java:67) at
com.intuit.karate.Match.(Match.java:53)
Yes this is a bug in Karate, we've opened an issue: https://github.com/intuit/karate/issues/678
The workaround suggested by #BabuSekaran will work:
* def response = { foo: 'a any b' }
* def temp = { foo: 'a any b' }
* match response contains temp

Using try except block in Odoo server action

I'm defining a server action in Odoo 10. Within this action I am trying to use the following code:
for data in datas:
try:
inventory_level = int(data[context['inventory_level_column']].strip())
except TypeError:
continue
However, I receive an error:
ValueError: <type 'exceptions.NameError'>: "name 'TypeError' is not defined"
Is it not possible to catch errors within the context of an Odoo server action? Why is TypeError not defined?
The code written on a server action is passed through to safe_eval method. There the __builtins__ are stripped and replaced (thus the exceptions.NameError class is removed.
You can check this behaviour on odoo/tools/safe_eval.py on the definition of safe_eval method. See globals_dict['__builtins__'] = _BUILTINS where _BUILTINS does not contain this exception.
Exception is the parent class of all exception classes, so if you want to catch exception then just specify top most parent class in except and in e you will get error message.
for data in datas:
try:
inventory_level = int(data[context['inventory_level_column']].strip())
except Exception ,e:
print e
pass

SQLExecDirect failed but SQLGetDiagRec has no data

I'm trying to setup some useful error handling in a program that used ODBC. According to documentation if SQLExecDirect returns SQL_ERROR I should be able to call SQLGetDiagRec to get SQL_STATE and possibly some messages, but in my tests when I call SQLGetDiagRec right after getting an error from SQLExecDirect I get SQL_NO_DATA returned and no information.
Code:
result = SQLExecDirect(hstmt, <SQL Statement>, SQL_NTS);
if(result == SQL_ERROR)
{
SQLSMALLINT msg_len = 0;
SQLCHAR sql_state[6], message[256];
SQLINTEGER native_error = 0;
result = SQLGetDiagRec(SQL_HANDLE_DBC, hDbc, 1, sql_state, &native_error, message, countof(message), &msg_len);
// Here 'result' is SQL_NO_DATA
....
}
It works in other cases, just not for SQLExecDirect for some reason. I'm also aware that one should cycle through the SQLGetDiagRec results, but if the very first one returns SQL_NO_DATA, according to documentation it means that there are no further ones.
The specific error that I was testing it with was requesting a non-existent table.
Is there anything else that I need to do in order obtain at least an error code, or does the diagnostic not work for errors that result from incorrect SQL requests?
When you call SQLGetDiagRec, pass SQL_HANDLE_STMT and your statement handle (hstmt in your example). That should return errors associated with that specific statement.

Rails 3 - how to make own error handler

could anyone help me, please, how to make my own error handler for example for the situation, when I am trying to destroy the item from database, that doesn't exist (delete item with don't exist ID)?
I tried to search on google, but I still haven't something, what works.
I guess you will never read this, but it can help others. You have a problem with .find cause it raise an exception when your id is wrong.
You have 3 ways to manage it.
You can catch the exception with a rescue. But that's not the best way.
You can check if your id exists, you have few ways to do this way. (count for example). But that's not the best way, cause you have 2 queries.
Or you can use find_by_id. This does not raise an exception, and return nil when your object does not exist. You only have to check about the result.
your_item = YourModel.find_by_id(non_existent_id) # returns nil
# PS: YourModel.find(non_existent_id) would raise exception
if your_item
your_item.destroy
flash[:notice] = "Deleted item with id #{non_existent_id}"
else
flash[:error] = "Cannot find item with id #{non_existent_id}"
end