Multi-Statement Table-Valued Function with a Cursor: How to Check If The Cursor is Still Open On Error?
Use a cursor variable (details here), then you don't have to worry about closing and deallocating (which, as David points out, isn't necessary inside a TVF, but it - and/or LOCAL - is required in other contexts). Just change:
 DECLARE c CURSOR ... FOR SELECT ...
 ...
 OPEN c;
 FETCH NEXT FROM c INTO ...

 ...

 CLOSE c;
 DEALLOCATE c;

To:
 DECLARE @c CURSOR;
 SET @c = CURSOR READ_ONLY FORWARD_ONLY FOR SELECT ...
 ...
 OPEN @c;
 FETCH NEXT FROM @c INTO ...

 ...


Work on the logic that you think requires a cursor and conditional/flow logic, so that you can eliminate the MSTVF and re-write it as an inline TVF. While it wasn't true before SQL Server 2012, I can assure you that most cursor logic in SQL Server 2016 can be rewritten using window functions. There are still isolated cases where a cursor is a better choice (not always for performance reasons), but it's doubtful that a TVF is one of them.