Home > Software engineering >  Deploying a Vapor app to Heroku fails because of " error: value of type 'URLSession'
Deploying a Vapor app to Heroku fails because of " error: value of type 'URLSession'

Time:12-12

I have created an application using Vapor and I want to deploy it to Heroku, but the push fails.

The build configuration looks like this

  • .swift-version: 5.5
  • use heroku-buildpack

The log looks like the following.

remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Building on the Heroku-20 stack
remote: -----> Using buildpack: https://github.com/vapor-community/heroku-buildpack
remote: -----> Swift app detected
remote: -----> Using Swift 5.5 (from .swift-version file)
remote: -----> Using built-in clang (Swift 5.5)
remote: -----> Installing swiftenv
remote: -----> Installing Swift 5.5
remote: Downloading https://swift.org/builds/swift-5.5-release/ubuntu2004/swift-5.5-RELEASE/swift-5.5-RELEASE-ubuntu20.04.tar.gz
remote: /tmp/swiftenv-5.5- /tmp/codon/tmp/buildpacks/66275d05cfaec82f8023e1ae68b013a22671c52f

.
.
.

remote: /tmp/build_ecf900fb/Sources/App/APIClient/APIClient.swift:61:34: error: value of type 'URLSession' has no member 'data
remote:         return try await session.data(for: request, delegate: nil)
remote:                          ~~~~~~~ ^~~~
remote: /tmp/build_ecf900fb/Sources/App/APIClient/APIClient.swift:61:63: error: 'nil' requires a contextual type
remote:         return try await session.data(for: request, delegate: nil)
remote:                                                               ^
remote:  !     Push rejected, failed to compile Swift app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !   Push rejected to apple-dev-news-ios.
remote: 
To https://git.heroku.com/apple-dev-news-ios.git
 ! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/apple-dev-news-ios.git'

APIClient.swift:61:63:

    private let session: URLSession

    .
    .
    .

    private func actuallySend(_ request: URLRequest) async throws -> (Data, URLResponse) {
        .
        .
        .
        return try await session.data(for: request, delegate: nil)
    }

Why is it failing and how can we make the push successful?

'data' is defined in the Foundation framework as follows.

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
extension URLSession {

    /// Convenience method to load data using an URLRequest, creates and resumes an URLSessionDataTask internally.
    ///
    /// - Parameter request: The URLRequest for which to load data.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data and response.
    public func data(for request: URLRequest, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse)
.
.
.

CodePudding user response:

The async APIs for Foundation on Linux aren't available yet (they're different from the actual language concurrency features).

For a Vapor app you shouldn't really be using URLSession to make requests, it doesn't fit with how the framework works. Use Vapor's client instead (which has async APIs)

  • Related