20

I am fully aware that Swift doesn't have a try/catch mechanism to catch exceptions (OK, Swift 2.0 now supports them). I also understand that many API methods return a NSError that will be filled with an error object if something goes wrong. So please don't point me to this question: Error-Handling in Swift-Language

But this still doesn't explain how to react to runtime errors in your own code, like array-out-of-bounds accesses or force-unwrapping an optional value that is nil. For example:

var test: String?
test = nil
println(test!) //oops!

or

var arr = [0,1,2]
for i = 0...3 {
    println(arr[i]) //oops!
}

Every programmer makes such mistakes occasionally and there should be a way to at least log them for later analysis. While debugging, Xcode can show us those, but what if this happens to an end-user or beta-tester? In pure C there is signal handling and it could be used in Objective-C as well. Is there something like this in Swift? A centralized callback entered just before the app dies?

Update:

Let me rephrase the question: in a large project, it is not feasible to manually check for the above errors on every loop and force-unwrapping. When a runtime error does happen eventually, is there a callback like Objective C's segfault handling or NSSetUncaughtExceptionHandler that will get called so that the error can be logged/e-mailed together with a stacktrace of the crash?

Community
  • 1
  • 1
Orlin Georgiev
  • 1,391
  • 16
  • 18

2 Answers2

1

Edit: This answer is not updated with swift 2.0. As swift now has error handling I have not updated the below answer. Some aspect of error handling will be updated in future with swift 3.0. You can follow this answer Error-Handling in Swift-Language

Swift is made to be typeSafe language.It get error at compile time rather than waiting to cause at runtime.

In first example you are using Optional.

var test: String?

First understand meaning of optional.When you specifying optional you are saying it could be nil or have no value.Now when you unwrapping test you are saying i know this value is not nil.Please unwrap it i am sure about that.So its your responsibility to see where it nil.If you are not sure about that than you should use optional binding here.When you are unsure about value always use if condition while unwrrapping

  if let notNilTest = test {
    //use notNilTest
  }
  else{
   //handle error
  }

In second example it should make sense to have the runtime exception handling but you can easily get this with if condition having count.So in second example as developer you should use if condition to get count of array.

From swift guide:

If you try to use subscript syntax to retrieve or set a value for an index that is outside of an array’s existing bounds, you will trigger a runtime error. However, you can check that an index is valid before using it, by comparing it to the array’s count property. Except when count is 0 (meaning the array is empty), the largest valid index in an array will always be count - 1, because arrays are indexed from zero.

They clearly mention about this and you should take care of these things to make your code less buggy.Some things they have provided and we should know about how to use these things.

Community
  • 1
  • 1
codester
  • 36,891
  • 10
  • 74
  • 72
  • 6
    This basically means "you handle errors by not doing any errors". Those examples are ultra-simple, but in a 50000-line project it will not be feasible or pretty to check for those on every single loop and force-unwrapping. And eventually runtime errors WILL happen. Then what? – Orlin Georgiev Oct 24 '14 at 10:36
  • If you are not using these things in practice it is very vulnerable and impractical to have on try catch block handle all these exception.Either you use try/catch or if condition.There are lot of mistakes also happen due to error handling and its valid debatable point.But it is always better to take preventive measures – codester Oct 24 '14 at 10:38
  • 5
    Objective C has signal handling and NSSetUncaughtExceptionHandler. Java has Thread.setDefaultUncaughtExceptionHandler. C# has AppDomain.UnhandledException. Note how those are not try/catch blocks, but centralized handlers in case all else fails. Why isn't there such a thing in Swift? It is not any safer than Java or C# – Orlin Georgiev Oct 24 '14 at 10:43
  • @OrlinGeorgiev - I also tried but I couldn't find a way to catch swift runtime errors.But crittercism does catch it. Have you found the solution ? – Durai Amuthan.H Feb 24 '16 at 06:29
  • @Durai No, Swift 2.0 still doesn't have a global exception handler – Orlin Georgiev Feb 24 '16 at 10:07
  • 2
    @OrlinGeorgiev - There must be a way I believe because Crittercism reports all the crashes that happens in my swift app. – Durai Amuthan.H Feb 24 '16 at 10:16
0

Consider using a guard statement instead of multiple if lets.

var arr = [0,1,2]
for i = 0...3 {
    Guard arr[i] != nil else {
        Continue
    }
    println(arr[i]) //oops!
}

Or instead of

if let x = some value {
    If let y = someOtherVal {
        If let z = yetanotherVal {
            Product = x * y* z
        }
    }
}

Is not nearly as neat as:

Let x = someVal
Let y = someOtherVal
Let z = yetAnotherVal

Guard x != nil,
  y != nil,
  z != nil
Else {
  Return
}

Product = x * y * z
Jeff Brown
  • 86
  • 8