Lua: no stack trace when calling error() without arguments? - error-handling

In Lua, calling the standard error() function with a message argument outputs the provided error message and also prints stack trace, e.g. executing the following code:
print("hello")
error("oops!")
print("world")
would result in the following output:
$ lua test.lua
hello
lua: test.lua:2: oops!
stack traceback:
[C]: in function 'error'
test.lua:2: in main chunk
[C]: ?
However, calling error() without arguments seems to make Lua die silently without printing stack trace. Executing this code:
print("hello")
error() // no arguments provided
print("world")
would result in this output:
$ lua test2.lua
hello
The documentation doesn't say anything about omitting the first message argument:
error (message [, level])
Terminates the last protected function called and returns message as
the error message. Function error never returns. Usually, error adds
some information about the error position at the beginning of the
message. The level argument specifies how to get the error position.
With level 1 (the default), the error position is where the error
function was called. Level 2 points the error to where the function
that called error was called; and so on. Passing a level 0 avoids the
addition of error position information to the message.
I'm wondering if this is intended behavior or no? IMO it would make sense to still print stack trace (and maybe output some default text e.g. error) even if no message is provided, because that's how the assert() function works.

The documentation doesn't say anything about omitting the first message argument:
Yes, it does, error() has a prototype like this:
error (message [, level])
Notice that only the arguments inside [] is optional, in this case level, otherwise the arguments are mandatory, in this case, message.
Comparing with the prototype of assert():
assert (v [, message])
As you can see, message in assert() is optional.

Related

Solidity Contract Unused Function/Parameter

function _postValidatePurchase (
address _beneficiary,
uint256 _weiAmount
)
pure internal
{
// optional override
}
When I compile I get this error in parts of my smart contract that mimic the function above: "Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.uint256 _weiAmount". However, when I comment out the uint and weiAmount, I get these errors :
DocstringParsingError: Documented parameter "_beneficiary" not found in the parameter list of the function.
DocstringParsingError: Documented parameter "_weiAmount" not found in the parameter list of the function.
libs/openzeppelin/crowdsale/Crowdsale.sol:105:5: TypeError: Wrong argument count for function call: 2 arguments given but expected 0.
_postValidatePurchase(_beneficiary, weiAmount);
regarding this line:
_postValidatePurchase(_beneficiary, weiAmount);
}
"Warning: Unused function parameter" is not an error, just a warning. If you have a function with parameters you are not using inside the function, why do you need them? You can just remove them from the input. The only case I can think of is when you are overriding the function. In any case, a warning does not prevent the contract from being compiled. You can just ignore the warning.

Unit Tests with Moq getting an error ""An expression tree may not contain a call or invocation that uses optional arguments""

I am writing Unit Tests with Moq when I suddenly encountered this error message while typing one of my Async methods:
"An expression tree may not contain a call or invocation that uses optional arguments"
However, when I was looking at my existing code, I was calling the code with just 1 argument.
Async Method definition:
public virtual async Task> Async(Guid fileId, MemoryStream stream = null)
scope.MyMock.Setup(x => x.Async(fileId)).Returns(Task.FromResult(Result.Ok(new ValidationResult())));
Gives me an error: "An expression tree may not contain a call or invocation that uses optional arguments". Please help.
You need to pass all arguments, even if they have a default value. In your case, the argument stream has a default value of null, but you still need to pass it.
So you could have this:
scope.MyMock.Setup(x => x.Async(fileId, null)).ReturnsAsync(Result.Ok(new ValidationResult()));

What is purpose of `unwrap()` if the return value is not used?

I found this Rust code for getting a line from stdin:
use std::io;
fn main() {
let mut line = String::new();
io::stdin().read_line(&mut line).unwrap();
println!("Input: {}", line);
}
io::stdin().read_line(&mut line) sets the line variable to a line read from stdin. From my understanding, read_line() returns a Result value, which can be pattern-matched, or .unwrap() can be used to get the inner value if it is not an Err.
However, the returned value of read_line() is never used. Only the line string variable is used, but people use .unwrap() most of the time even if it is not used.
What is the purpose of unwrap() if the returned value is not used? Just to throw an error?
What is the purpose of unwrap() if the returned value is not used? Just to throw an error?
Yes, but that's not all.
Ignoring potential errors is bad; there's a big difference between an empty line and a line that's not been read because of an error; for example in a typical "pipeline" command in a shell, the program needs to stop when it stops receiving input, otherwise the user has to kill it.
In C, ignoring errors is too easy. Many languages solve this by having exceptions, but Rust doesn't.
In order to avoid the issue plaguing C programs that it's too easy to forget to check the return code, normally Rust functions will bundle the expected return value and error in Result, so that you have to check it to get the return value.
There is one potential issue left, however: what if the caller doesn't care about the return value? Most notably, when the value is (), nobody really cares about it.
There is a bit of compiler magic invoked here: the Result structure is tagged with the #[must_use] attribute. This attribute makes it mandatory to do something with Result when it's returned.
Therefore, in your case, not only is unwrapping good, it's also the simplest way to "do something" and avoid a compilation warning.
If you don't want to "elegantly" handle cases where there is a failure to read a line from stdin (e.g. by attempting it once again or picking a default value), you can use unwrap() to trigger a panic; it silences the warning caused by a Result that is not used:
warning: unused result which must be used
--> src/main.rs:5:5
|
5 | io::stdin().read_line(&mut line);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default

NullReferenceException on bool, int, or other stack variable

First of all: the title of this post does not match the actual question I have.
But I am also supplying the answer to the original problem (NullRefExcp on bool), so other users will find it's solution here by the chosen title.
I have a class, similar to the following:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
Today I had the problem that func crashed with a NullReferenceException at some point although it had been executed successfully many times before.
The exception occured in the line if (!m_bInit)!
I know, you all are saying now, that this is impossible. But it actually was this line. The reason was following:
I have two different variables, both named oTest, but at different places. One of them was initialized: oTest = gcnew CTest. Calling func on this oTest worked well. The first call of func on the other oTest failed with the exception from above. The curious thing is, that the crash seems to happen at the query on m_bInit, also the stacktrace of the exception tells so. But this was just the first place where a member of the not initialized object (it was still nullptr) was called.
Therefore, the advice for other users with the same problem: Check the stack backwards to find a function call on an object that is nullptr/null.
My question now is:
Why does the execution not fail on the first call of a function of oTest which is nullptr?
Why is the function entered and executed until the first access to a member?
Actually, in my case 3 functions were entered and a couple of variables were created on the stack and on the heap...
This code:
void func()
{
if (!m_bInit)
return;
...
}
could actually be written as:
void func()
{
if (!this->m_bInit)
return;
...
}
Hopefully now you can see where the problem comes from.
A member function call is just a regular function call that includes the this parameter implicitly (it's passed along with the other parameters).
The C++/CLI compiler won't perform a nullptr check when calling non-virtual functions - it emits a call MSIL opcode.
This is not actually the case in C#, since the C# compiler will emit the callvirt MSIL opcode even for non-virtual functions. This opcode forces the JIT to perform a null check on the target instance. The only ways you could get this error in C# is by calling the function via reflection or by generating your own IL that uses the call opcode.

Proper use of reasons

My test code has the following assert:
testSubscriber.Called.Should().BeTrue("the handler was not called");
When it fails I get the following error message:
Expected True because the handler was not called, but found False.
English is not my native language, but this does not sound right, what should I write in the reason?
The reason should be the reason why your assertion should pass. In your case, it appears you instead wrote the reason it would fail.
That parameter will be directly substituted into failure message. It will make sure not to repeat the word "because", so you can include that in the string which may make the code read more clearly.
Regarding the English for this particular case, the exact language I would use would depend on the situation.
If you are asserting that calling the handler sets Called to true, you might say case:
testSubscriber.Called.Should().BeTrue("because the handler was called");
which would result in the message
Expected True because the handler was called, but found False.
If you are confident that calling the handler will set Called to true, and you are instead trying to assert that the handler was called:
testSubscriber.Called.Should()
.BeTrue("we expected the handler to have been called");
which would result in the message
Expected True because we expected the handler to have been called, but found False.