So is there any correct way to annotate futures in scaladoc (specifically failures)? #throws doesn't seem appropriate since the exceptions get wrapped in a Try (Failure). Was looking for something like a #failure tag.
/**
* #failure FooException If i is even
* #failure BarException If i is odd
*/
def foo(i: Int) = Future {
i match {
case i if i % 2 == 0 => throw new FooException()
case _ => throw new BarException()
}
}
Related
I'm newbee to Dart.
I have troubles to find an easy to read way to "safely" access a List element at any index
final List<String> myList = <String>[]
myList.add("something")
// ...
String myGetter(int index) {
// "heavy" way
if (index < myList.length) {
return myList[index]
}
return null;
}
If I go with regular [index] or elementAt(index) and index is out of boundaries, it throws a RandeError
Is there a method that returns null when the index cannot be reached?
Sorry if double posted, but I try to find the info without any success, + not sure if there is an (un)official slack / discord to ask this kind of "easy" questions
Dart lists do not allow invalid indices. There is no built-in way to get a null when trying. Not in the platform libraries.
You can create your own helper function (like you already do):
T? tryGet<T>(List<T> list, int index) =>
index < 0 || index >= list.length ? null : list[index];
(Remember to check for negative indices too).
As suggested, you can also add it as an extension method:
extension ListGetExtension<T> on List<T> {
T? tryGet(int index) =>
index < 0 || index >= this.length ? null : this[index];
}
which may make it more pleasant to work with.
(I recommend against doing something bad and then catching the error, at least when you can easily check up-front whether it's bad or not).
You can defined an extension method to catch the RangeError and return null:
void main() {
print([1, 2].get(3)); // display null
}
extension SafeLookup<E> on List<E> {
E get(int index) {
try {
return this[index];
} on RangeError {
return null;
}
}
}
You can try this
void main() {
List<int> teste = [1, 2, 3, 4];
print(teste.get(1));
}
extension ListExtension<E> on List<E> {
dynamic get(int value) {
return this.contains(value) ? value : null;
}
}
According to the documentation:
throws a RangeError if index is out of bounds.
So you can use the try-catch block:
String myGetter(int index) {
try {
return myList[index];
}
on RangeError {
// Called when the index is out of bounds
return null;
}
}
If you want to be extra cautious I guess you could put a generic catch at the end (to catch all kinds of throws that are not RangeError), but in a simple getter like this I think that would not be necessary:
[...]
}catch (e) {
// No specified type, handles all other types of error/exceptions
return null;
}
[...]
I have a problem in a Grails 3.3.8 application after the upgrade from Grails 2.5.6.
I have a service which using Row.findAll() to get records from an H2 database. Then it creates a list of closures for future execution. Then the list is running by a ThreadExecutor via invokeAll(). In each closure I get data via Row.findById().
It is working when I run program, but it does not work in integration tests. I checked that Row.findAll().size() returns 0 inside the closure but just before the invokeAll() it returns a positive number.
Update:
I prepare small test for that:
#Integration
#Rollback
class TestSpec extends Specification {
void "test something"() {
when:
f()
then:
g()
}
private void f() {
Raw raw = new Raw()
raw.text = "text"
raw.save(flush: true)
}
private void g() {
Closure closure = {
try {
def x = rawService.getRawSize()
if (x != 1) throw new Exception("A: x = " + x)
} catch (Exception e) {
e.printStackTrace()
throw e
}
}
def x = rawService.getRawSize()
executorService.invokeAll([closure])
}
}
The code above is not working. It throws an Exception.
Wrap the body of your f() method in a Raw.withNewSession block. This will save your new instance in a separate session. After the closure is finished the session will close, persisting your instance and allowing it to be accessed in another session or thread.
private void f() {
Raw.withNewSession {
Raw raw = new Raw()
raw.text = "text"
raw.save(flush: true)
}
}
While visiting a compilation unit--- and given a certain condition- I would like to apply a transformation (using the => operator) and count the number of times the same transformation was applied for a given compilation unit.
I was able to perform that using a kind of "global module variable", but I am quite sure that it is possible to combine both replacements and actions within a single visit expression. Is that possible?
module MultiCatch
import lang::java::\syntax::Java18;
import ParseTree;
import IO;
import Map;
import Type;
import List;
// sure, I don't like global variables.
//
// However I could not find a way to perform both
// a replacement and count the number of times
// it was applied in the same compilation unit.
int numberOfOccurences = 0;
/**
* Refactor a try-catch statement to use the
* MultiCatch construct of Java 7.
*/
public tuple[int, CompilationUnit] refactorMultiCatch(CompilationUnit unit) {
numberOfOccurences = 0;
CompilationUnit cu = visit(unit) {
case (TryStatement)`try <Block b1> <Catches c1>` => (TryStatement)`try <Block b1> <Catches mc>`
when mc := computeMultiCatches(c1)
};
return <numberOfOccurences, cu>;
}
/*
* Based on a simple notion of similarity,
* this function calculates the possible
* occurences of MultiCatch.
*/
private Catches computeMultiCatches(cs){
map [Block, tuple[list[CatchType], VariableDeclaratorId, Block] ] mCatches =();
visit(cs){
case(CatchClause)`catch (<CatchType t> <VariableDeclaratorId vId>) <Block b>` :{
if (b in mCatches){
<ts, vId, blk> = mCatches[b];
ts += t;
mCatches[b] = <ts, vId, blk>;
numberOfOccurences += 1;
}
else{
mCatches[b] = <[t], vId, b>;
}
}
}
return generateMultiCatches([mCatches[b] | b <- mCatches]);
}
/*
* Creates a syntactic catch clause (either a simple one or
* a multicatch).
*
* This is a recursive definition. The base case expects only
* one tuple, and than it returns a single catch clause. In the
* recursive definition, at least two tuples must be passed as
* arguments, and thus it returns at least two catches clauses
* (actually, one catch clause for each element in the list)
*/
private Catches generateMultiCatches([<ts, vId, b>]) = {
types = parse(#CatchType, intercalate("| ", ts));
return (Catches)`catch(<CatchType types> <VariableDeclaratorId vId>) <Block b>`;
};
private Catches generateMultiCatches([<ts, vId, b>, C*]) = {
catches = generateMultiCatches(C);
types = parse(#CatchType, intercalate("| ", ts));
return (Catches)`catch(<CatchType types> <VariableDeclaratorId vId>) <Block b> <CatchClause+ catches>`;
};
One way to do it is using a local variable and a block with an insert:
module MultiCatch
import lang::java::\syntax::Java18;
import ParseTree;
import IO;
import Map;
import Type;
import List;
/**
* Refactor a try-catch statement to use the
* MultiCatch construct of Java 7.
*/
public tuple[int, CompilationUnit] refactorMultiCatch(CompilationUnit unit) {
int numberOfOccurences = 0; /* the type is superfluous */
CompilationUnit cu = visit(unit) {
case (TryStatement)`try <Block b1> <Catches c1>` : {
numberOfOccurences += 1;
mc = computeMultiCatches(c1)
insert (TryStatement)`try <Block b1> <Catches mc>`;
}
};
return <numberOfOccurences, cu>;
}
The {...} block allows multiple statements to be executed after the match;
The local variable is now only present in the frame of refactorMultiCatch;
The insert statement has the same effect as the previous => arrow did;
Since the match := always succeeds, I changed the when clause into a simple assigment
There is also other more complex ways to share state in Rascal, but I personally prefer to have state not escape the lexical scope of a function.
I'm looking for the proper way to return a custom error from a JSON-RPC exposed class.
JSON-RPC has a special format for reporting error conditions. All errors need to provide, minimally, an error message and error code; optionally, they can provide additional data, such as a backtrace.
Error codes are derived from those recommended by the XML-RPC EPI project. Zend\Json\Server appropriately assigns the code based on the error condition. For application exceptions, the code ‘-32000’ is used.
I will use the divide method of the sample code from documentation to explain:
<?php
/**
* Calculator - sample class to expose via JSON-RPC
*/
class Calculator
{
/**
* Return sum of two variables
*
* #param int $x
* #param int $y
* #return int
*/
public function add($x, $y)
{
return $x + $y;
}
/**
* Return difference of two variables
*
* #param int $x
* #param int $y
* #return int
*/
public function subtract($x, $y)
{
return $x - $y;
}
/**
* Return product of two variables
*
* #param int $x
* #param int $y
* #return int
*/
public function multiply($x, $y)
{
return $x * $y;
}
/**
* Return the division of two variables
*
* #param int $x
* #param int $y
* #return float
*/
public function divide($x, $y)
{
if ($y == 0) {
// Say "y must not be zero" in proper JSON-RPC error format
// e.g. something like {"error":{"code":-32600,"message":"Invalid Request","data":null},"id":null}
} else {
return $x / $y;
}
}
}
$server = new Zend\Json\Server\Server();
$server->setClass('Calculator');
if ('GET' == $_SERVER['REQUEST_METHOD']) {
// Indicate the URL endpoint, and the JSON-RPC version used:
$server->setTarget('/json-rpc.php')
->setEnvelope(Zend\Json\Server\Smd::ENV_JSONRPC_2);
// Grab the SMD
$smd = $server->getServiceMap();
// Return the SMD to the client
header('Content-Type: application/json');
echo $smd;
return;
}
$server->handle();
p.s. Yes I tried Google search.
Disclaimer: I have no experience in using Zend\Json\Server whatsoever :)
If you talk about an error response, I can correlate that to the Server::fault() method (also available on Github). So I assume if fault() is called and injected into the respones, it would return the response with error messages according to your referred recommended XML-RPC server standard.
The handler method proxies the actual work to _handle() (linked to the source) where a try/catch is encapsuling the dispatching to the (in your case) Calculator class.
The fault is called based on the exception message and exception code. As such I think it's simply throwing an exception and setting the right message/code there:
use Zend\Json\Server\Error;
class Calculator
{
public function divide($x, $y)
{
if (0 === $y) {
throw new InvalidArgumentException(
'Denominator must be a non-zero numerical',
Error::ERROR_INVALID_PARAMS
);
}
// Rest here
}
// Rest here
}
PS. I also changed your error code here, as to me, it feels -32602 (invalid params) is more appropriate than -32600 (invalid request.
I am looking for a way to create a function with a variable number of arguments or parameters in Dart. I know I could create an array parameter instead, but I would prefer to not do that because I'm working on a library where syntactic brevity is important.
For example, in plain JavaScript, we could do something like this (borrowed from here):
function superHeroes() {
for (var i = 0; i < arguments.length; i++) {
console.log("There's no stopping " + arguments[i]);
}
}
superHeroes('UberMan', 'Exceptional Woman', 'The Hunk');
However, in dart, that code will not run. Is there a way to do the same thing in dart? If not, is this something that is on the roadmap?
You can't do that for now.
I don't really know if varargs will come back - they were there some times ago but have been removed.
However it is possible to emulate varargs with Emulating functions. See the below code snippet.
typedef OnCall = dynamic Function(List arguments);
class VarargsFunction {
VarargsFunction(this._onCall);
final OnCall _onCall;
noSuchMethod(Invocation invocation) {
if (!invocation.isMethod || invocation.namedArguments.isNotEmpty)
super.noSuchMethod(invocation);
final arguments = invocation.positionalArguments;
return _onCall(arguments);
}
}
main() {
final superHeroes = VarargsFunction((arguments) {
for (final superHero in arguments) {
print("There's no stopping ${superHero}");
}
}) as dynamic;
superHeroes('UberMan', 'Exceptional Woman', 'The Hunk');
}
Dart does indirectly support var-args as long as you aren't too much into syntactic brevity.
void testFunction([List<dynamic> args=[]])
{
for(dynamic arg:args)
{
// Handle each arg...
}
}
testFunction([0, 1, 2, 3, 4, 5, 6]);
testFunction();
testFunction([0, 1, 2]);
Note: You can do the same thing with named parameters, but you'll have to handle things internally, just in case if the user (of that function; which could be you) decides to not pass any value to that named parameter.
I would like to thank #Ladicek for indirectly letting me know that a word like brevity exists in English.
This version:
Works with both positional and keyword arguments.
Supports typing of the return value.
Works with modern Dart.
typedef VarArgsCallback = void Function(List<dynamic> args, Map<String, dynamic> kwargs);
class VarArgsFunction {
final VarArgsCallback callback;
static var _offset = 'Symbol("'.length;
VarArgsFunction(this.callback);
void call() => callback([], {});
#override
dynamic noSuchMethod(Invocation inv) {
return callback(
inv.positionalArguments,
inv.namedArguments.map(
(_k, v) {
var k = _k.toString();
return MapEntry(k.substring(_offset, k.length - 2), v);
},
),
);
}
}
void main() {
dynamic myFunc = VarArgsFunction((args, kwargs) {
print('Got args: $args, kwargs: $kwargs');
});
myFunc(1, 2, x: true, y: false); // Got args: [1, 2], kwargs: {x: true, y: false}
}
Thanks, Alexandre for your answer!
I played around a little with Alexandre Ardhuin's answer and found that we can tweak a couple of things to make this work in the current version of Dart:
class VarArgsClass {
noSuchMethod(InvocationMirror invocation) {
if (invocation.memberName == 'superheroes') {
this.superheroes(invocation.positionalArguments);
}
}
void superheroes(List<String> heroNames) {
for (final superHero in heroNames) {
print("There's no stopping ${superHero}!");
}
}
}
main() {
new VarArgsClass().superheroes('UberMan', 'Exceptional Woman', 'The Hunk');
}
This has lots of problems, including:
A warning is generated wherever you call superheroes() because the signature doesn't match your parameters.
More manual checking would need to be done to make sure the list of arguments passed to superheroes is really a List<String>.
Needing to check the member name in noSuchMethod() makes it more likely you'll forget to change the 'superheroes' string if you change the method name.
Reflection makes the code path harder to trace.
BUT if you are fine with all of those issues, then this gets the job done.
If you are really into syntactic brevity, just declare a function/method with say 10 optional positional parameters and be done. It's unlikely someone will call that with more than 10 arguments.
If it sounds like a hack, that's because it is a hack. But I've seen the Dart team doing the same :-)
For example:
void someMethod(arg0, [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9]) {
final args = [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9];
args.removeWhere((value) => value == null);
/* do something the the args List */
print(args);
}
For the example you've written, I think you're best off using a list. Sorry about that!
I'm looking at dartbug.com, but I don't see a feature request for this. You're definitely welcome to create one!