Попытка правильно разобраться с ошибками и опциями - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь использовать SwiftSoup для очистки HTML. Этот пример, основанный на документации giftub SwiftSoup, работает нормально…

func scrape() throws {

  do {
    let htmlFromSomeSource = "<html><body><p class="nerp">HerpDerp</p><p class="narf">HoopDoop</p>"

    let doc = try! SwiftSoup.parse(htmlFromSomeSource)
    let tag = try! doc.select("p").first()!
    let tagClass = try! tag.attr("class")
  } catch {
    print("oh dang")
    throw Abort(.notFound)
  }
  print(tagClass)
}

… До тех пор, пока я не связался с целевыми объектами селектора или атрибута, и в этот момент все вылетает из строя благодаря неявно развернутым опциям (я полагаю, это был просто быстрый и грязный код для начала более умных людей). Это делает / ловит, кажется, не помогает вообще.

Так в чем же правильный путь? Это компилирует ...

print("is there a doc?")
guard let doc = try? SwiftSoup.parse(response.body.description) else {
  print("no doc")
  throw Abort(.notFound)
}

print("should halt because there's no img")
guard let tag = try? doc.select("img").first()! else {
  print("no paragraph tag")
  throw Abort(.notFound)
}

print("should halt because there's no src")
guard let tagClass = try? tag.attr("src") else {
  print("no src")
  throw Abort(.notFound)
}

... но опять же, если я возиться с селектором или атрибутом, он вылетает: «Неожиданно обнаружен ноль при развертывании необязательного значения» (после «есть документ?»). Я думал, что охранник остановит процесс, когда он столкнется с нулем? (Если я конвертирую «try?» В «try», компилятор жалуется, что «инициализатор для условного связывания должен иметь необязательный тип»…)

1 Ответ

0 голосов
/ 27 апреля 2018

Если вы объявляете функцию как throws, вам не нужен блок do - catch внутри функции. Просто удалите блок и восклицательные знаки после try, чтобы передать ошибки в функцию вызывающего абонента.

func scrape() throws { // add a return type
    let htmlFromSomeSource = "<html><body><p class="nerp">HerpDerp</p><p class="narf">HoopDoop</p>"

    let doc = try SwiftSoup.parse(htmlFromSomeSource)
    guard let tag = try doc.select("p").first() else { throw Abort(.notFound) }
    let tagClass = try tag.attr("class")
    // return something 
}
...