def submit_to_queue(self, script_file):
        """
        Public API: wraps the concrete implementation _submit_to_queue

        Raises:
            `self.MaxNumLaunchesError` if we have already tried to submit the job max_num_launches
            `self.Error` if generic error
        """
        if not os.path.exists(script_file):
            raise self.Error('Cannot find script file located at: {}'.format(script_file))

        if self.num_launches == self.max_num_launches:
            raise self.MaxNumLaunchesError("num_launches %s == max_num_launches %s" % (self.num_launches, self.max_num_launches))

        # Call the concrete implementation.
        s = self._submit_to_queue(script_file)
        self.record_launch(s.qid)

        if s.qid is None:
            raise self.Error("Error in job submission with %s. file %s \n" %
                            (self.__class__.__name__, script_file) +
                             "The error response reads:\n %s \n " % s.err +
                             "The out response reads:\n %s \n" % s.out)

        # Here we create a concrete instance of QueueJob
        return QueueJob.from_qtype_and_id(self.QTYPE, s.qid, self.qname), s.process