Handling errors from Swift 2.0 String object functions - string

I'm new to Swift 2.0 programming (coming from the world of C#), and I'm simply trying to write a function to parse some data from a string and return the result. The function itself works well, but as part of the process, the string functions may throw and error if the input string is improperly formatted and I would like to prepare a catch-all error handler for the function to deal with this. Here's the code for the original function without error handling:
// Parses the numeric value of the BATT return string
private func parseBatteeryLevel(inputStr : String) -> Int {
if inputStr.hasPrefix("BATT") && inputStr.containsString("%") {
let start = inputStr.startIndex.advancedBy(5)
let end = inputStr.characters.indexOf("%")?.advancedBy(-1)
if end != nil {
return Int(inputStr.substringWithRange(start...end!))!
}else{
return 0
}
}else{
printStatus("Return Value Parse Error: \"\(inputStr)\"")
return 0
}
}
As you can see, I did implement a basic sanity check for the strings that could be inputted but it is by no means exaustive. My primary concern is what happens if is passes the checks, but causes the advanceBy() or any of the internal string functions to fail?
I did try to wrap the code in a do-catch block as shown below,
private func parseBatteeryLevel(inputStr : String) -> Int {
if inputStr.hasPrefix("BATT") && inputStr.containsString(" ") {
do {
let start = try inputStr.startIndex.advancedBy(5)
let end = try inputStr.characters.indexOf("%")?.advancedBy(-1)
if end != nil {
return try Int(inputStr.substringWithRange(start...end!))!
}else{
return 0
}
} catch let error as NSError {
printStatus(error.description)
}
}else{
printStatus("Return Value Parse Error: \"\(inputStr)\"")
return 0
}
}
but then I get warnings, next to all the lines inside the do block, marked with the try keyword saying,
No calls to throwing functions occur within 'try' expression
Then, there is another warning next to the catch keyword saying,
'catch' block is unreachable because no errors are thrown in 'do' block
This doesn't make sense because the function clearly crashes the program if an invalid string is entered. This would be painfully simple to deal with in C# but what is the proper way to handle this in Swift 2.0?

So the problem String startIndex and characters functions do not throw and exception that can be caught by the swift do try catch block. See The Swift Programming Language (Swift 2.1) - Error Handling documentation for more info.
So I rewrote the code to deal with parsing of the integer without crashing
func parseBatteeryLevel(inputStr : String) -> Int {
if inputStr.hasPrefix("BATT") && inputStr.containsString("%") {
let start = inputStr.startIndex.advancedBy(5)
let indexOfPercent = inputStr.characters.indexOf("%")
if (indexOfPercent != nil) {
let end = indexOfPercent!.advancedBy(-1)
let batteryLevel = inputStr.substringWithRange(start...end)
if let level = Int(batteryLevel) {
return level
}
}
return 0
} else {
print("Return Value Parse Error: \"\(inputStr)\"")
return 0
}
}

Related

Discuss how the finally block works

I am using Visual Studio 2019, and I have a piece of code that uses finally block, I have declared a std::string object at the beginning of each Test1(), Test2() and Test3() functions.
I put a break point inside the finally block of each function to see the str variable, and as a result the str variable is reset to Empty in the Test1() and Test2() functions. Only in Test3() function is not reset.
I discovered that str is reset if a return statement is encountered before entering the finally block.
I don't understand what is going on, in the code of my software there are many places where finally block is used like the example above, I need to understand the exact mechanism of it so that I can fix potential bugs in the application.
The following is the code of the Test functions
void Test1()
{
string str = "Test1";
try
{
int* i = NULL;
*i = 0; //This command will raise an exception
return;
}
catch (Exception^ e)
{
return;
}
finally
{
int i = 0; //'str' is rested as empty when entering here
}
}
void Test2()
{
string str = "Test2";
try
{
int* i = NULL;
return;
}
catch (Exception^ e)
{
return;
}
finally
{
int i = 0; //'str' is rested as empty when entering here
}
}
void Test3()
{
string str = "Test3";
try
{
int* i = NULL;
}
catch (Exception^ e)
{
}
finally
{
int i = 0; //'str' is NOT reset to empty when entering here
}
}
Thank you so much!
I debug and double check, found that destructor of local variables will be destroyed when encountering return statement, destructor is called before entering finally block. Only if no return statement is encountered will these destructors be called after the Finally block (regardless of whether an exception occurs or not).
Due to this inconsistency, I could only work around it by not using any finally blocks in the code anymore, replacing it with goto statements or equivalent.
P/S: I am configuring the project with SEH Exceptions (/EHa) option.

How to Return Nil String in Go?

I have a function which returns a string under certain circumstances, namely when the program runs in Linux or MacOS, otherwise the return value should be nil in order to omit some OS-specific checks further in code.
func test() (response string) {
if runtime.GOOS != "linux" {
return nil
} else {
/* blablabla*/
}
}
however when I try to compile this code I get an error:
test.go:10:3: cannot use nil as type string in return argument.
If I return just an empty string like return "", I cannot compare this return value with nil further in code.
So the question is how to return a correct nil string value?
If you can't use "", return a pointer of type *string; or–since this is Go–you may declare multiple return values, such as: (response string, ok bool).
Using *string: return nil pointer when you don't have a "useful" string to return. When you do, assign it to a local variable, and return its address.
func test() (response *string) {
if runtime.GOOS != "linux" {
return nil
} else {
ret := "useful"
return &ret
}
}
Using multiple return values: when you have a useful string to return, return it with ok = true, e.g.:
return "useful", true
Otherwise:
return "", false
This is how it would look like:
func test() (response string, ok bool) {
if runtime.GOOS != "linux" {
return "", false
} else {
return "useful", true
}
}
At the caller, first check the ok return value. If that's true, you may use the string value. Otherwise, consider it useless.
Also see related questions:
How do I represent an Optional String in Go?
Alternatives for obtaining and returning a pointer to string: How do I do a literal *int64 in Go?
Go has built-in support for multiple return values:
This feature is used often in idiomatic Go, for example to return both result and error values from a function.
In your case it could be like this:
func test() (response string, err error) {
if runtime.GOOS != "linux" {
return "", nil
} else {
/* blablabla*/
}
}
And then:
response, err := test()
if err != nil {
// Error handling code
return;
}
// Normal code
If you want to ignore the error, simply use _:
response, _ := test()
// Normal code
Go allows multiple return types. So use this to your advantage and return an error or any other type. Check this out for more info: http://golangtutorials.blogspot.com/2011/06/return-values-from-go-functions.html?m=1

Eclipse JDT resolve unknown kind from annotation IMemberValuePair

I need to retrieve the value from an annotation such as this one that uses a string constant:
#Component(property = Constants.SERVICE_RANKING + ":Integer=10")
public class NyServiceImpl implements MyService {
But I am getting a kind of K_UNKNOWN and the doc says "the value is an expression that would need to be further analyzed to determine its kind". My question then is how do I perform this analysis? I could even manage to accept getting the plain source text value in this case.
The other answer looks basically OK, but let me suggest a way to avoid using the internal class org.eclipse.jdt.internal.core.Annotation and its method findNode():
ISourceRange range = annotation.getSourceRange();
ASTNode annNode = org.eclipse.jdt.core.dom.NodeFinder.perform(cu, range);
From here on you should be safe, using DOM API throughout.
Googling differently I found a way to resolve the expression. Still open to other suggestions if any. For those who might be interested, here is a snippet of code:
if (valueKind == IMemberValuePair.K_UNKNOWN) {
Annotation ann = (Annotation)annotation;
CompilationUnit cu = getAST(ann.getCompilationUnit());
ASTNode annNode = ann.findNode(cu);
NormalAnnotation na = (NormalAnnotation)annNode;
List<?> naValues = na.values();
Optional<?> optMvp = naValues.stream()
.filter(val-> ((MemberValuePair)val).getName().getIdentifier().equals(PROPERTY))
.findAny();
if (optMvp.isPresent()) {
MemberValuePair pair = (MemberValuePair)optMvp.get();
if (pair.getValue() instanceof ArrayInitializer) {
ArrayInitializer ai = (ArrayInitializer)pair.getValue();
for (Object exprObj : ai.expressions()) {
Expression expr = (Expression)exprObj;
String propValue = (String)expr.resolveConstantExpressionValue();
if (propValue.startsWith(Constants.SERVICE_RANKING)) {
return true;
}
}
}
else {
Expression expr = pair.getValue();
String propValue = (String)expr.resolveConstantExpressionValue();
if (propValue.startsWith(Constants.SERVICE_RANKING)) {
return true;
}
}
}
//report error
}
private CompilationUnit getAST(ICompilationUnit compUnit) {
final ASTParser parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(compUnit);
parser.setResolveBindings(true); // we need bindings later on
CompilationUnit unit = (CompilationUnit)parser.createAST(null);
return unit;
}

Compare Strings in Swift unit test

How do you test whether two Strings are equal in a Swift unit test? I've tried the == operator but it doesn't recognize it:
import XCTest
#testable import MyProject
class MyProject: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
XCTAssertNil(nil, "This test works")
}
func toJSONTest() {
let currentLocation = deviceLocation(timestamp: "2015-11-02 16:32:15 +0000",latitude: "40.2736577695212",longitude: "-111.715408331498")
var MyProjectStatuses = [MyProjectStatus(id: "", currentLocation: currentLocation)]
let json = ""
XCTAssertTrue(json == "")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock {
// Put the code you want to measure the time of here.
}
}
}
And the actual method being tested from MyProject.swift:
func toJSON ()->String{
var json = ""
json = "{\"myproject_status\":"
json = json + "{\"id\":\"" + self.Id + "\""
return json
}
This part:
XCTAssertTrue(json == "")
Throws:
Operator is not a known binary operator
The problem is that toJSONTest is not a test. Change the name to testToJSON.
This works fine on my machine:
func testToJSON() {
let json = ""
XCTAssertTrue(json == "")
}
The test runs, and passes. However, I would probably write it like this:
func testToJSON() {
let json = ""
XCTAssertEqual(json, "", "They are not equal")
}
Although this question is explicitly about how to compare two Strings in a Swift unit test, what's implicit in the question is how to compare two JSON Strings. I just wanted to point out that the right thing to do when comparing two JSON strings is to parse the JSON Strings to a Foundation object with the JSONSerialization class and then to compare the resulting Foundation objects. This approach takes care of the problem of the two JSON Strings having slightly different formatting or fields in a different order. So, for example, it's important that "{\"a\":1,\"b\":2}" and "{\"b\":2,\"a\":1}" are deemed to be equal because they are logically equal.
Here's a Swift function I put together which helps with this comparison:
class JSONAssert {
class func assertEquals(expected: String, actual: String) {
let expectedData = Data(expected.utf8)
let actualData = Data(actual.utf8)
let expectedObject: Any
let actualObject: Any
do {
expectedObject = try JSONSerialization.jsonObject(with: expectedData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `expected` (i.e. \(expected)): \(error)")
return
}
do {
actualObject = try JSONSerialization.jsonObject(with: actualData, options: [])
} catch {
XCTFail("Failed constructing a Foundation object from `actual` (i.e. \(actual)): \(error)")
return
}
guard let expectedDictionary = expectedObject as? NSDictionary else {
XCTFail("Failed casting expected object (i.e. \(expectedObject)) to an NSDictionary")
return
}
guard let actualDictionary = actualObject as? NSDictionary else {
XCTFail("Failed casting actual object (i.e. \(actualObject)) to an NSDictionary")
return
}
XCTAssertEqual(expectedDictionary, actualDictionary)
}
}

function return values c#

I am trying to get to grips with C# having not coded for many years and my previous experience being in ANSI C.
I have read a number of books and searched online but one aspect is evading me and I am hoping someone here can help.
In the past I would declare a function and if there was a possibility of something not happening within the function (i.e. file not found etc.) declare the return to be an integer. I would then return 0 if all was well and a value if not. The value would correspond to where the function failed to execute fully and I could branch accordingly from where I called it.
if(function1())
{
// all my error stuff, maybe a switch/case etc.
}
All the examples I have found in C# seem to avoid this technique and I was hoping to get some understanding here.
Thanks in anticipation.
(I know I am a fossil). :)
Exceptions are the approach you use in C# and similar languages.
It goes like this:
try
{
function();
}
catch(FileNotFoundException e)
{
// File not found
}
catch(UnauthorizedAccessException e)
{
// User doesn't have right to access file
}
// etc...
To make this work, function shouldn't return a status code but instead throw an exception in case of an error.
Please note that the exceptions I illustrated in the code block above are thrown by the framework if you try to access a file and one of those errors is happening. So you don't actually have to do this yourself.
Furthermore, in C# there is no implicit conversion from integral values to bool, i.e. if(function()) is invalid, if function returns an int. You would need to write it like this:
if(function() != 0)
{
// all your error stuff
}
There's nothing to stop you doing this (though there are better ways of handling the errors - exceptions for example).
If you do want to carry on with this approach, the biggest problem you are having is that in C# you can't treat an integer as a boolean so your if test won't compile. What you need is:
if (function1() != 0)
{
}
But to check the value you'd need:
int result = function1();
switch (result)
{
case 1:
// Handle this case
break;
case 2:
// Handle this case
break;
default:
// All OK
break;
}
It would be better to return an enumerated type for each error case so that you don't have magic numbers, but exceptions are the way to go:
try
{
function1();
}
catch (SpecificException1 e1)
{
// Handle this case
}
catch (SpecificException2 e2)
{
// Handle this case
}
What you shouldn't have is a general exception handler:
catch (Exception e)
{
}
This just hides other potential problems.
If you want to follow that pattern of checking return value instead of managing errors, you better use enumarations than plain numbers.
For example:
public enum ResultType
{
Error = 0,
Success,
Waiting
}
public ResultType function()
{
if (still_waiting)
return ResultType.Waiting;
if (error_has_occured)
return ResultType.Error;
return ResultType.Success;
}
public void Main()
{
ResultType result = function();
switch (result)
{
case ResultType.Success:
MessageBox.Show("all is good");
break;
case ResultType.Waiting:
MessageBox.Show("still waiting...");
break;
case ResultType.Error:
MessageBox.Show("error has occurred");
break;
}
}
Behind the scenes, it's still using numbers but you put some meaning to each number.
if(function()==1)
{
}
int function()
{
int returnVal =0;
// do stuff
// if true return returnVal =1 else set returnVal =0;
return returnVal;
}

Resources