Skip to content

[SourceKit] Fail requests when an error occurs #24124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 22, 2019

Conversation

DavidGoldman
Copy link
Contributor

Previously, requests would fail silently by returning an empty struct
in the response.

With this change, responses will properly report fail with the internal
error.

This allows IDEs to:

  • Properly identify errors when they occur
  • Choose to display the error to the user or perhaps handle it

Previously, requests would fail silently by returning an empty struct
in the response.

With this change, responses will properly report fail with the internal
error.
@akyrtzi
Copy link
Contributor

akyrtzi commented Apr 18, 2019

I like the idea of providing messages on why that specific source location did not resolve to a symbol but I'm not so sure about failing the request because of it. Request failures are more about the client providing a malformed request or something went wrong with sourcekitd (e.g. it crashed), they should not be happening if both the client and sourcekitd are operating properly.

@DavidGoldman
Copy link
Contributor Author

What would the alternative be though? For all of these failures, the general information struct will be completely empty. Maybe a new response type should be added? It seems odd to add an error field to each potential response (which would only be set by itself).

FWIW, findRelatedIdents already had this behavior. I understand where you're coming from, but from an IDE's point of view the request did fail, it's just unclear if it's intentional.

@akyrtzi
Copy link
Contributor

akyrtzi commented Apr 18, 2019

What would the alternative be though? For all of these failures, the general information struct will be completely empty. Maybe a new response type should be added? It seems odd to add an error field to each potential response (which would only be set by itself).

The cursor info response could get an extra field with a message that is set only when a symbol could not be resolved in that particular source location, as justification.

FWIW, findRelatedIdents already had this behavior.

Do you mean that findRelatedIdents is failing the request if you don't point to a symbol ? I'm not able to reproduce this.

I'm not aware of a request that works like this, for example code-completion is not failing the request if it doesn't find any symbols to return at a particular source location.

I understand where you're coming from, but from an IDE's point of view the request did fail, it's just unclear if it's intentional.

The IDE can already see that no symbol is present at that specific source location, if it wants to also show a message or log it for debugging purposes it can pick it up from the the extra field.

@DavidGoldman
Copy link
Contributor Author

What would the alternative be though? For all of these failures, the general information struct will be completely empty. Maybe a new response type should be added? It seems odd to add an error field to each potential response (which would only be set by itself).

The cursor info response could get an extra field with a message that is set only when a symbol could not be resolved in that particular source location, as justification.

FWIW, findRelatedIdents already had this behavior.

Do you mean that findRelatedIdents is failing the request if you don't point to a symbol ? I'm not able to reproduce this.

Ah my bad, it's actually editorFindInterfaceDoc that has this behavior (although the Error is included in the info). See here.

I'm not aware of a request that works like this, for example code-completion is not failing the request if it doesn't find any symbols to return at a particular source location.

I understand where you're coming from, but from an IDE's point of view the request did fail, it's just unclear if it's intentional.

The IDE can already see that no symbol is present at that specific source location, if it wants to also show a message or log it for debugging purposes it can pick it up from the the extra field.

Gotcha. I think part of this change makes sense to keep as failure: e.g. bad invocations, if you think that the cursor info in particular should be changed to add a field as well let me know.

@akyrtzi
Copy link
Contributor

akyrtzi commented Apr 18, 2019

I think bad invocations (e.g. missing compiler arguments) are fine to fail the request. To make the distinction (should something fail the request or not) think of it like this:

If it is possible to know in advance that the request is going to fail (e.g. some field is missing, or the compiler arguments don't include the file you want information from), then this is failable. If there is no way for the client to know in advance just by looking at the request (e.g. there is no symbol at a source location, or no completion results at that location), then the response should not be that the request itself is erroneous.

@DavidGoldman
Copy link
Contributor Author

I think bad invocations (e.g. missing compiler arguments) are fine to fail the request. To make the distinction (should something fail the request or not) think of it like this:

If it is possible to know in advance that the request is going to fail (e.g. some field is missing, or the compiler arguments don't include the file you want information from), then this is failable. If there is no way for the client to know in advance just by looking at the request (e.g. there is no symbol at a source location, or no completion results at that location), then the response should not be that the request itself is erroneous.

What do you think of the case when an internal error occurs (something unexpected happened)? Still don't fail the request?

Anyways, then for both the CursorInfo and NameInfo, a new Error field should be added? Or should I just leave it as is with an empty response?

@akyrtzi
Copy link
Contributor

akyrtzi commented Apr 18, 2019

What do you think of the case when an internal error occurs (something unexpected happened)? Still don't fail the request?

They should fail the request, abnormal situations like sourcekitd crashing, or other unexpected things, should fail the request.

Anyways, then for both the CursorInfo and NameInfo, a new Error field should be added? Or should I just leave it as is with an empty response?

How about adding an internal_diagnostic string field in the response that will be present in situations where the response is currently empty ?

@DavidGoldman
Copy link
Contributor Author

What do you think of the case when an internal error occurs (something unexpected happened)? Still don't fail the request?

They should fail the request, abnormal situations like sourcekitd crashing, or other unexpected things, should fail the request.

Anyways, then for both the CursorInfo and NameInfo, a new Error field should be added? Or should I just leave it as is with an empty response?

How about adding an internal_diagnostic string field in the response that will be present in situations where the response is currently empty ?

Yeah that sounds reasonable, I'll go ahead and add that

@DavidGoldman
Copy link
Contributor Author

Added the InternalDiagnostic, please take another look

@DavidGoldman
Copy link
Contributor Author

Friendly ping

@@ -12,4 +12,4 @@ let a = 12
// rdar://problem/38162017
// REQUIRES: OS=macosx

// CHECK: <empty cursor info>
// CHECK: (Request Failed): Unable to resolve the start of the token
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rintaro, in your fix for rdar://30346106 you had the request return an empty response for out-of-range offset, are you ok with the response failing instead ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it should be OK.

@DavidGoldman
Copy link
Contributor Author

Made the changes you requested, please let me know if the RequestResult looks good as I'm not super familiar with C++

@DavidGoldman
Copy link
Contributor Author

Friendly ping

@gottesmm gottesmm requested a review from akyrtzi May 15, 2019 18:53
@gottesmm
Copy link
Contributor

(Just an FYI, @DavidGoldman I did a friendly re-request review drive by.)

sourcekitd_variant_dictionary_get_string(Info, KeyInternalDiagnostic);
if (InternalDiagnostic) {
OS << "<diagnostic \"" << InternalDiagnostic << "\">\n";
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, this makes it look like a (true) failure instead of just an empty result. I suggest something like

<empty cursor info>
<internal diagnostic "...">

Or

<empty cursor info; internal diagnostic: "...">

@DavidGoldman
Copy link
Contributor Author

Made the requested fixes

Copy link
Contributor

@akyrtzi akyrtzi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this!

@akyrtzi
Copy link
Contributor

akyrtzi commented May 21, 2019

@swift-ci smoke test

@DavidGoldman
Copy link
Contributor Author

No problem! let me know if i need to merge/rebase onto master

@akyrtzi akyrtzi merged commit 729a955 into swiftlang:master May 22, 2019
@akyrtzi
Copy link
Contributor

akyrtzi commented May 22, 2019

Could you open a PR for swift-5.1 branch ?

@DavidGoldman
Copy link
Contributor Author

Will do, how much time do you think I have though?

@akyrtzi
Copy link
Contributor

akyrtzi commented May 22, 2019

There's time; worst can happen is we reject it if it is too late.

@jckarter
Copy link
Contributor

This is causing a bunch of tests to fail in CI:

https://ci.swift.org/job/oss-swift-incremental-ASAN-RA-osx/3368/consoleText

Failing Tests (7):
Swift(macosx-x86_64) :: SourceKit/Refactoring/syntactic-rename.swift
Swift(macosx-x86_64) :: SourceKit/Misc/edit_range.swift
Swift(macosx-x86_64) :: SourceKit/Indexing/index_module_missing_depend.swift
Swift(macosx-x86_64) :: SourceKit/DocSupport/doc_source_file.swift
Swift(macosx-x86_64) :: SourceKit/CursorInfo/invalid_offset.swift
Swift(macosx-x86_64) :: SourceKit/CompileNotifications/arg-parsing.swift
Swift(macosx-x86_64) :: SourceKit/CodeComplete/complete_open.swift

I'm going to revert.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants