I'm using a Sentinel policy inside a Terraform Cloud workspace. My policy is rather simple:
import "tfplan/v2" as tfplan
allBDs = tfplan.find_resources("aci_bridge_domain")
violatingBDs = tfplan.filter_attribute_does_not_match_regex(allBDs,
"description", "^demo(.+)", true)
main = rule {
length(violatingBDs["messages"]) is 0
}
Unfortunately, it fails when invoked with this message:
An error occurred: 1 error occurred:
* ./allowed-terraform-version.sentinel:3:10: key "find_resources" doesn't support function calls
The documentation and source for find_resources (doc) expects a string, yet the Sentinel interpreter seems to think I'm invoking a method of tfplan? It's quite unclear why that is, and the documentation doesn't really help.
Any ideas?
OK I found the issue. If I paste the code for find_resources and its dependencies (to_string, evaluate_attribute) then everything works as expected.
So I have a simple import problem and need to figure out how to properly import https://raw.githubusercontent.com/hashicorp/terraform-guides/master/governance/third-generation/common-functions/tfplan-functions/tfplan-functions.sentinel
I'm writing a Go application which has a database package. Now in database package there are a couple of methods which you can call for getting an entity based on some fields.
I was wondering what is the best practice for error handling in Go when no entity is found. Should I return errors in my own database package or return nil as the value?
I know google's datastore returns error when no entity is found.
Right now I'm using gorm and it also returns error when no entity is found.
I'm wondering you can simply return nil as the value instead of returning an error. Am I missing a point?
If you are using gorm, there is a function specifically for that; namely,
// IsRecordNotFoundError returns true if error contains a RecordNotFound error
func IsRecordNotFoundError(err error) bool {}
You can use it as following:
err = db.Find(object).Error
if err != nil {
if gorm.IsRecordNotFoundError(err) {
// handle object not found
} else {
return err
}
}
and for your question:
I'm wondering you can simply return nil as the value instead of returning an error
It really depends on your design; so if you want to separate your database layer, then you should still inform the user about this error using your own exported error type and let them handle it as they wish.
you can use this code:
user:=&User{}
if db.First(&user, "username=?", mobile).RecordNotFound() {
return nil
}
return user
I wrote a function using dbListTables from the DBI package, that throws a warning that I cannot understand. When I run the same code outside of a function, I don't get the warning message.
For info, the database used is Microsoft SQL Server.
Reproducible example
library(odbc)
library(DBI)
# dbListTables in a function: gives a warning message
dbListTablesTest <- function(dsn, userName, password){
con <- dbConnect(
odbc::odbc(),
dsn = dsn,
UID = userName,
PWD = password,
Port = 1433,
encoding = "latin1"
)
availableTables <- dbListTables(con)
}
availableTables <-
dbListTablesTest(
dsn = "myDsn"
,userName = myLogin
,password = myPassword
)
# dbListTables not within a function works fine (no warnings)
con2 <- dbConnect(
odbc::odbc(),
dsn = "myDsn",
UID = myLogin,
PWD = myPassword,
Port = 1433,
encoding = "latin1"
)
availableTables <- dbListTables(con2)
(Incidentally, I realise I should use dbDisconnect to close a connection after working with it. But that seems to throw similar warnings. So for the sake of simplicity I've omitted dbDisconnect.)
The warning message
When executing the code above, I get the following warning message when using the first option (via a function), but I do not get it when using the second option (no function).
warning messages from top-level task callback '1'
Warning message:
Could not notify connection observer. trying to get slot "info" from an object of a basic class ("character") with no slots
The warning is clearly caused by dbListTables, because it disappears when I omit that line from the above funtion.
My questions
Why am I getting this warning message?
More specifically why am I only getting it when calling dbListTables via a function?
What am I doing wrong / should I do to avoid it?
My session info
R version 3.4.2 (2017-09-28)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=Dutch_Belgium.1252 LC_CTYPE=Dutch_Belgium.1252 LC_MONETARY=Dutch_Belgium.1252 LC_NUMERIC=C LC_TIME=Dutch_Belgium.1252
attached base packages:
[1] stats graphics grDevices utils datasets tools methods base
other attached packages:
[1] DBI_0.7 odbc_1.1.3
loaded via a namespace (and not attached):
[1] bit_1.1-12 compiler_3.4.2 hms_0.3 tibble_1.3.4 Rcpp_0.12.13 bit64_0.9-7 blob_1.1.0 rlang_0.1.2
Thanks in advance for any help!
TL:DR calling odbc::dbConnect within another function causes this warning.
After a lot of digging in the odbc github, I have found the source of the warning. Calling dbConnect creates a db connection. Within this function is the following code:
# perform the connection notification at the top level, to ensure that it's had
# a chance to get its external pointer connected, and so we can capture the
# expression that created it
if (!is.null(getOption("connectionObserver"))) { # nocov start
addTaskCallback(function(expr, ...) {
tryCatch({
if (is.call(expr) && identical(expr[[1]], as.symbol("<-"))) {
# notify if this is an assignment we can replay
on_connection_opened(eval(expr[[2]]), paste(
c("library(odbc)", deparse(expr)), collapse = "\n"))
}
}, error = function(e) {
warning("Could not notify connection observer. ", e$message, call. = FALSE)
})
# always return false so the task callback is run at most once
FALSE
})
} # nocov end
This warning call should look familiar. This is what generates the warning. So why does it do that?
The snippet above is trying to do some checking on the connection object, to see if everything went well.
How it does that, is by adding a function checking this to the 'TaskCallBack'. This is a list of functions that get executed after a top-level task is completed. I am not 100% sure on this, but from what I can tell, this means that these functions are executed after the highest function in the call stack finishes.
Normally, this would be a line in your script. So for example:
library(odbc)
con <- odbc::dbConnect(odbc::odbc(), ...)
After the assignment in the second line is finished, the following function is executed:
function(expr, ...) {
tryCatch({
if (is.call(expr) && identical(expr[[1]], as.symbol("<-"))) {
# notify if this is an assignment we can replay
on_connection_opened(eval(expr[[2]]), paste(
c("library(odbc)", deparse(expr)), collapse = "\n"))
}
}, error = function(e) {
warning("Could not notify connection observer. ", e$message, call. = FALSE)
}
}
The top-level expression gets passed to the function and used to check if the connection works. Another odbc function called on_connection_opened then does some checks. If this throws an error anywhere, the warning is given, because of the tryCatch.
So why would the function on_connection_opened crash?
The function takes the following arguments:
on_connection_opened <- function(connection, code)
and one of the first things it does is:
display_name <- connection#info$dbname
Which seems to match the warning message:
trying to get slot "info" from an object of a basic class ("character") with no slots
From the name of the argument, it is clear that the function on_connection_opened expects a database connection object in its first argument. What does it get from its caller? eval(expr[[2]])
This is the lefthand side of the original call: con
In this case, this is a connection object and everything is nice.
Now we have enough information to answer your questions:
Why am I getting this warning message?
Your function creates a connection, which queues up the check connection function. If then checks for a list of tables and returns that. The check connection function then interprets the list of tables as if it is a connection, tries to check it, and fails miserably. This throws the warning.
More specifically why am I only getting it when calling dbListTables via a function?
dbListTables is not the culprit, dbConnect is. Because you are calling it from within a function, it doesn't get the connection object it is trying to check back and fails.
What am I doing wrong / should I do to avoid it?
A workaround would be to open a connection separately and pass that into your function. This way the connection gets opened in its own call, so the check works properly.
Alternatively, you can remove the TaskCallback again:
before <- getTaskCallbackNames()
con <- odbc::dbConnect(odbc::odbc(), ...)
after <- getTaskCallbackNames()
removeTaskCallback(which(!after %in% before))
Is the running is on_connection_opened essential? What does it do exactly?
As explained by the package's creator in this comment on Github, the function handles the displaying of the connection in the connections tab in RStudio. This is not that interesting to look at if you close the connection in the same function again. So this is not essential for your function.
I try to run a query which filters for a KeyProperty.
The dart gcloud package I am currently using is version: 0.2.0+8
So for a Model like this:
#Kind(idType: IdType.String)
class Foo extends Model {
#ModelKeyProperty(indexed: true, required: true)
Key bar;
}
I would like to run a query like so:
Query query = new Query(db, Foo);
query.filter('bar =', someKey);
var result = query.run();
but I receive following error:
Uncaught error in request handler: ApplicationError: Cannot encode unsupported Key type.
#0 Codec.encodeProperty (package:appengine/src/api_impl/raw_datastore_v3_impl.dart:319:7)
#1 DatastoreV3RpcImpl.query (package:appengine/src/api_impl/raw_datastore_v3_impl.dart:527:43)
#2 Query.run.<anonymous closure> (package:gcloud/src/db/db.dart:232:28)
Assuming
import 'package:gcloud/datastore.dart' as datastore;
import 'package:gcloud/db.dart';
In my previous experiments, I remember having to convert the Key (from db.dart) to a datastore.Key. I don't know why this API expects this while the others handle db.Key correctly so I cannot tell whether it is a bug or not but the following should work:
await db.withTransaction((Transaction transaction) async {
// convert the key to a datastore key
datastore.Key datastoreKey = db.modelDB.toDatastoreKey(someKey);
// query by bar key
Query query = transaction.query(Foo, ancestorKey);
query.filter('bar =', datastoreKey);
await query.run().listen((Model model) {
print(model.key.id);
}).asFuture();
});
Update: I've figured out it is because I have a 'Link' in my schema, I want the field 'createdBy' to link to the OUser class of the user, but I can't seem to make that link. Somehow when the function creates the V it doesn't inherit the field type from the class. Any ideas?
-
I've got an issue writing using functions. I want to write to the Database but I cant. if I commit using the normal orient.getGraph() I get the following error: (OrientDB Version 2.0.7)
Error on parsing script at position #0: Error on execution of the script
Script: newConcept
------^
sun.org.mozilla.javascript.WrappedException: Wrapped com.orientechnologies.orient.core.exception.OStorageException: Error during transaction commit. (
<Unknown source>#26) in
<Unknown source> at line number 26
Wrapped com.orientechnologies.orient.core.exception.OStorageException: Error during transaction commit. (
<Unknown source>#26)
Error during transaction commit.
null
And if I try it with the non-transactional it just doesn't write.
I am sending a post request, I've tried enabling Javascript server side scripting but that is not the issue.
Here is my whole function:
var graph = orient.getGraph();
var currentUserId = getCurrentUserId();
var currentTimeStamp = getCurrentDateString();
//Check if the className is not specified or if the class does not exist.
if(graph.getVertexType(className)==null){
//return an Error message
return response.send(500, 'Class does not exist', "application/json", '{ "error": "Class does not yet exist or a blank class was specified, please create the class first." }' );
}
//The var v wraps OrientVertex class
var v = graph.addVertex('class:' + className);
if (label) { v.setProperty('label', label); }
if (value) { v.setProperty('value', value); }
v.setProperty('createdBy', currentUserId);
v.setProperty('createdAt', currentTimeStamp);
//Commit
graph.commit();
return v;