I think @harpo answered the question adequately in a comment. Here's some additional info, in case it helps.
You can bind a key to a command that deletes the frame, and if error "Attempt..." is raised then kill Emacs instead. For that, use
condition-case to handle the error. That way you can use a single key to either delete a frame or, if it is the last one, kill Emacs.
(defun delete-frame-or-kill-emacs ()
"Delete the selected frame. If the last one, kill Emacs."
(condition-case nil (delete-frame) (error (kill-emacs))))
(global-set-key [remap delete-frame] 'delete-frame-or-kill-emacs)
(However, I wouldn't recommend using such a command, as it is too easy to accidentally kill Emacs.)
Update after your comment.
If you are using emacsserver and emacsclient then try
(save-buffers-kill-terminal) instead of
(kill-emacs). That should delete the frame but keep the server alive. I didn't see that you had specified that you were in such a context. (
save-buffers-kill-terminal is bound to
C-x C-c in a client frame.) See the Emacs manual, node
And in that case,
C-x C-c should be all you need - it sounds like it does just what you are asking for. And if you prefer that it be invoked from another key then just bind that key to