Looking through a lot of new code for #2230931: Supporting multiple item types per index, I came across a lot of instances (especially in IndexInterface) where a boolean return value was used to indicate success or failure of an operation. In any language that supports exceptions, I think that's an anti-pattern which we should avoid. Especially since, as far as I can see, we don't even check the return value most of the times (which is, of course, exactly the problem with using the return value for error detection).

Of course, when switching to exceptions, we should definitely take care to always catch exceptions at some point further up the calling chain, they should only leave the module in a few instances (when searching, for example). Also, we of course need to make sure to always document which exceptions can be thrown by a method/function.

I would then also like to remove the hasValid*() methods, which externalize error detection logic all over the module. (I.e., in all instances where you request, e.g., a datasource, you have to remember to do hasValidDatasource() beforehand.)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alarcombe’s picture

IME using exceptions as part of normal program flow is the anti-pattern. :) FWIW, I always recommend against using exceptions, except in exceptional circumstances - namely that the method cannot be completely executed because of (typically) a resource issue (out of memory, file cannot be created etc).

There's a good article here on why exceptions can be considered worse than GOTOS:

1. They are invisible in the source code. Looking at a block of code, including functions which may or may not throw exceptions, there is no way to see which exceptions might be thrown and from where. This means that even careful code inspection doesn't reveal potential bugs.
2. They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function. Every time you call a function that can raise an exception and don't catch it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn't think about.

http://www.joelonsoftware.com/items/2003/10/13.html

Food for thought?

freblasty’s picture

I'll have to agree with alarcombe, exceptions should be used in exceptional circumstances and not for normal program flow.

drunken monkey’s picture

First off, regarding "invisible in the source code": That's why you have to take extra care to always add the appropriate @throws declarations (transitively – i.e., if you call a method that can throw an exception, either catch it or also declare it).
I admit, this is a lot easier in Java or other languages that force you to explicitly declare the exceptions that can be thrown. But still, I don't really see how a boolean return type is any more visible in the code – in both cases, you have to check the documentation of the method you are calling to learn about this.

But, and here comes the crucial part: if you are sloppy with return types, you often won't notice it. E.g., we currently completely ignore the return values of IndexInterface::insertItems() (and the other tracking methods in the index). If tracking doesn't work, the admin will never get notified, they might just, at some point, notice that the numbers are off.
If we'd make the same mistake with an exception, as soon as the error state would occur the user (or, probably, a developer at some point, long before a stable release) would get a big, ugly exception screen – and complain about it in the issue queue, enabling us to easily fix this.

However, foremost I don't actually see the issue you are having here. Apart from the "invisible in the source code" part, I fully agree with you. Exceptions should only be used for exceptional states, never (or only after careful consideration) for normal control flow.
But that's exactly what we have here: an index should always have a valid tracker, a valid datasource (or, soon, valid datasource plugins for all its enabled datasources) and a valid server (unless it is disabled). Otherwise, there was some incompatible code change or the user has uninstalled a module we depend on – in both cases, this is an exceptional state in which we cannot work normally anymore, and which the user should be immediately notified about.

Nick_vh’s picture

I have to agree with drunkenmonkey here and defend exceptions in those cases. It allows also to be much more verbose as to what exactly happened and what you can return to the user. You could in theory make a contract with negative numbers and return those from your core functions so you know what exactly went wrong but that wouldn't solve much in the long run.

Exceptions make total sense in the context of required parameters. We just have to make sure there is a good scope as to where we catch those exceptions and handle them properly (as drunkenmonkey mentioned earlier).

freblasty’s picture

So exceptions will only be used for exceptional circumstances. However if we remove all hasValid*() methods than then users with a misconfigured or broken configuration index/server will be unable to correct their error using the UI as it will generate an exception when retrieving e.g. getTracker() or getDatasource(). We should still allow developers to prevent an exception from occurring when possible.

amateescu’s picture

will be unable to correct their error using the UI as it will generate an exception when retrieving e.g. getTracker() or getDatasource().

Shouldn't we catch the exceptions in this case and inform the user through a drupal_set_message() or something?

freblasty’s picture

Why would we want to catch an exception if we can prevent on from occurring and show a message? Currently the index/server overview page already provide this functionality and will report "Missing or invalid plugin".

drunken monkey’s picture

Shouldn't we catch the exceptions in this case and inform the user through a drupal_set_message() or something?

Yes, exactly. We just have to catch the exception at the right stage, and enabling the user to actually fix the broken configuration is of course one of the criteria here.

Why would we want to catch an exception if we can prevent on from occurring and show a message?

Because it's an exceptional state, and that's exactly what exceptions are for. And of course we still want to show a message. But we don't want to have a contract where we force every caller of a method to first call another method to ensure the call is legal. With exceptions, we can encapsulate that whole logic in a clean way, instead of necessitating callers to know about such internal logic.

freblasty’s picture

I'm for using exceptions when someone call getDatasource() and throw an exception when something is wrong. However we should still provide methods to check whether something is broken to keep code cleaner and not writing exception driven code.

In a normal workflow for indexing items I would not check for a valid datasource and use exception handling as we expect the all plugins should be working correctly.

For an overview or edit page however instead of writing try-catch, a simple hasValid*() is much cleaner.

drunken monkey’s picture

OK, I agree, it does make sense in some cases. Especially in edit forms, when we want to ignore the error anyways.
(At least for the tracker and server – in my code from #2230931: Supporting multiple item types per index, getDatasources() just ignores invalid plugins, which will be the desired behavior anyways, and which will probably be used in overviews and edit forms, too. Only when a specific datasource is requested, which is invalid, an exception is thrown.)

Is everyone in line with this, or does someone think we should always use exceptions?

amateescu’s picture

Another possiblity is to use the concept of "broken/null" plugins when we encounter a missing plugin. Core (actually, Views) uses it a lot and there's also an issue to 'formalize' it: #1822048: Introduce a generic fallback plugin mechanism

Some other related core issues:
#1881630: [meta] Determine how to respond to invalid plugins (plugin dependencies)
#2178795: Allow DiscoveryInterface::getDefinition() to throw an exception for an invalid plugin

Edit: I'm +1 on #10 :)

drunken monkey’s picture

Personally, I don't like the concept of returning "broken" plugin stubs much and wouldn't see the added value.
Would you be in favor of it, or did you just want to mention it?

amateescu’s picture

I'm not super familiar with all our codebase and its needs at the moment, so I just wanted to mention it :)

amateescu’s picture

After working a bit on the code affected by this decision, I can offer another option, taken from one of the issues referenced in #11: introduce a $exception_on_invalid = TRUE argument, which is pretty much self-explanatory :)

drunken monkey’s picture

Ah, yes, I saw that in that issue, too.
Personally, I find this a very ugly pattern, though, adding needless complexity and making the code harder to understand. I've also never seen this pattern anywhere before, though I have to admit that doesn't necessarily mean its not used. So, if there is no fervent support for this option, I wouldn't go with that but just continue with hasValid*().

Berdir’s picture

The pattern has been taken from Symfony's Container::get(), but I agree that it's ugly, that's why the referenced issue introduced a hasDefinition() that should be used in most cases for plugins managers. hasValid*() sounds like a similar pattern.

Agree with what's being said, we should both provide methods to check if something can be executed, then you can use those for example in the UI and in case the method is called anyway, then throwing an exception is the right thing to do.

amateescu’s picture

Status: Active » Needs review
FileSize
7.02 KB

After all the cleanup that already went in with #2230931: Supporting multiple item types per index, this is all that I could find.

amateescu’s picture

FileSize
8.04 KB
1.02 KB

Found one failing test :)

Berdir’s picture

+++ b/search_api_db/src/Tests/SearchApiDbTest.php
@@ -706,8 +707,14 @@ class SearchApiDbTest extends EntityUnitTestBase {
+    $index = entity_load('search_api_index', $this->indexId);
+    try {
+      $index->clear();
+      $this->pass('The index was successfully cleared.');
+    }
+    catch (SearchApiException $e) {
+      $this->fail('The index could not be cleared cleared.');
+    }

Do we really need this? In case it does fail, this will actually hide the exception/reason why it didn't work? I think that construct is only useful if an exception is the expected cases that you want to pass...

amateescu’s picture

FileSize
7.86 KB
651 bytes

Yep, you're right :)

drunken monkey’s picture

Status: Needs review » Needs work
  1. +++ b/src/Entity/Index.php
    @@ -937,11 +937,9 @@ class Index extends ConfigEntityBase implements IndexInterface {
       public function reindex() {
    -    if ($this->status() && !$this->isReadOnly() && $this->hasValidTracker()) {
    +    if ($this->status() && !$this->isReadOnly()) {
           $this->getTracker()->trackAllItemsUpdated();
    -      return TRUE;
         }
    -    return FALSE;
       }
     
       /**
    @@ -990,11 +988,10 @@ class Index extends ConfigEntityBase implements IndexInterface {
    
    @@ -990,11 +988,10 @@ class Index extends ConfigEntityBase implements IndexInterface {
        * {@inheritdoc}
        */
       public function clear() {
    -    if ($this->reindex() && $this->isServerEnabled()) {
    +    if ($this->isServerEnabled()) {
    +      $this->reindex();
           $this->getServer()->deleteAllItems($this);
    -      return TRUE;
         }
    -    return FALSE;
       }
    

    I think reindex() should also work for read-only indexes. It only influences tracking after all.

    However, clear absolutely has to check whether the index is read-only before deleting the items on the server.
    So:

    public function clear() {
      if (status()) {
        reindex();
        if (!isReadOnly()) {
          getServer()->deleteAllItems();
        }
      }
    }
    
  2. +++ b/src/Index/IndexInterface.php
    @@ -390,9 +390,6 @@ interface IndexInterface extends ConfigEntityInterface {
        * Marks all items in this index for reindexing.
    -   *
    -   * @return bool
    -   *   TRUE if the operation was successful, FALSE otherwise.
        */
       public function reindex();
     
    @@ -446,9 +443,6 @@ interface IndexInterface extends ConfigEntityInterface {
    
    @@ -446,9 +443,6 @@ interface IndexInterface extends ConfigEntityInterface {
     
       /**
        * Clears all items in this index and marks them for reindexing.
    -   *
    -   * @return bool
    -   *   TRUE if the operation was successful, FALSE otherwise.
    

    These also need new @throws tags.

Also, the main focus of this issue was getServer() and getTracker(), which seem to not have been changed. So that should be added, too.
But other than that, this looks good.

Do we really need this? In case it does fail, this will actually hide the exception/reason why it didn't work? I think that construct is only useful if an exception is the expected cases that you want to pass...

Doesn't it fail more horrible when there is an uncaught exception than just producing a fail? But the message would be handy, you're right – we could maybe just include it in the fail() message?

amateescu’s picture

Status: Needs work » Needs review
FileSize
11.04 KB
4.46 KB

Right, updated getServer() and getTracker() and added @throws to reindex() and clear().

About the test, a fail is still a fail that needs to be looked at/fixed, so horrible or not doesn't really matter :)

drunken monkey’s picture

Component: Backend » Framework

About the test, a fail is still a fail that needs to be looked at/fixed, so horrible or not doesn't really matter :)

What I meant is that sometimes exceptions completely end the test, while with a fail you will also see the remaining assertions. I don't know if that would be the case here, though. Of course the developer will have to fix it in any case, but when the test doesn't error out, he/she might have more information to do that.

drunken monkey’s picture

Status: Needs review » Reviewed & tested by the community

The patch looks good now, though. Thanks!

  • Commit 92c66f7 on master by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...
amateescu’s picture

Status: Reviewed & tested by the community » Fixed

Yay :) Rerolled and committed.

  • Commit 92c66f7 on master, views by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...
Berdir’s picture

What I meant is that sometimes exceptions completely end the test, while with a fail you will also see the remaining assertions. I don't know if that would be the case here, though. Of course the developer will have to fix it in any case, but when the test doesn't error out, he/she might have more information to do that.

It's by test method, and there's nothing else in that test method anyway I think? The only thing that fails horribly are fatal errors, exceptions are caught and logged by Simpletest.

Also, PHPUnit by default stops on the first exception/assertion fail, because everything that follows after it is in at least 9 of 10 cases just noise that confused people and they try to fix things that are only a follow-up error of the actual problem :) I've seen that many times ;)

alarcombe’s picture

We appear to have this as a commonly used pattern now, but if getBackend() doesn't return a valid object then we just terminate with a fatal error trying to call removeIndex on a non-object.

  try {
      $this->getBackend()->removeIndex($index);
    }
    catch (SearchApiException $e) {
      $vars = array(
        '%server' => $this->label(),
        '%index' => is_object($index) ? $index->label() : $index,
      );
      watchdog_exception('search_api', $e, '%type while removing index %index from server %server: !message in %function (line %line of %file).', $vars);
      $this->tasksAdd(__FUNCTION__, $index);
    }

This is where I get nervous about exceptions, no matter what the language or framework :) As I see it we have the following options, none of which are good
a) getBackend needs to throw a SearchApiException exception if it can't return an object (even though this is not an 'exceptional' circumstance for that method.
b) if getBackend returns null we return FALSE (or something semantically correct)
c) (my preference, for consistency), we throw (and catch) a SearchApiException if getBackend is null eg

try {
  if(!$backend = $this->getBackend()) {
    throw new SearchApiException("Failed to get backend");
  }
  $backend->removeIndex();
  catch (SearchApiException $e) {
    ...handle exception etc...
  }
}

  • Commit 92c66f7 on master, views, htmlfilter by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...
drunken monkey’s picture

Status: Fixed » Needs work

Ah, you're right of course, I/we totally missed that method! So yes, that should definitely also throw an exception.

a) getBackend needs to throw a SearchApiException exception if it can't return an object (even though this is not an 'exceptional' circumstance for that method.

Yes it is. A server always needs to have a backend, otherwise someone has uninstalled a needed module. (Which reminds me: #2257081: Make sure to handle uninstalled modules providing plugins correctly.)

I also spotted now that Index::getServer() doesn't abide to its contract and also throws an exception if no server was set for the index (and not only when an non-existent one was set). This should now be fixed.

amateescu’s picture

Status: Needs work » Fixed
FileSize
1.56 KB

Oops :)

i saw that you fixed Index::getServer() in http://drupalcode.org/sandbox/daeron/2091893.git/commit/f915803974581c05..., so I committed this patch for Server::getBackend().

  • Commit 3c5a651 on master by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
drunken monkey’s picture

Excellent, thanks!

  • Commit 6d05a25 on master by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
drunken monkey’s picture

Oops, a bit too quick: we still lacked the proper @throws documentation for getBackend(), and we didn't check all locations where it got called. Should be alright now, though.

  • Commit 3c5a651 on master, views by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    

  • Commit 6d05a25 on master, views by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

  • Commit 3c5a651 on master, views, htmlfilter by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, 2230881-test-all-processors by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, 2230881-test-all-processors by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, 2230881-test-all-processors by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743 by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743 by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743 by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2 by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2 by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, 2235381-fix-config-schemas, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2 by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords, ignorecase-nick, renamefields by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords, ignorecase-nick, renamefields by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords, ignorecase-nick, renamefields by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords, ignorecase-nick, renamefields by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords, ignorecase-nick, renamefields by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, move-integration-tests-subfolder, issue-2273743, 2268885-fix-validation, synonyms-processor, 2230925-server-tasks, 2235381-fix-config-schemas-2, 2257113-Index-Processors-Fields, config-schema, transliteration, ignore-case-test-fix, 2281233-fix-stopwords, ignorecase-nick, renamefields by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick, 2247923-Test_the_RenderedItem_processor by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick, 2247923-Test_the_RenderedItem_processor by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick, 2247923-Test_the_RenderedItem_processor by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...

  • Commit 3c5a651 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick, 2247923-Test_the_RenderedItem_processor, 2286813-fields-processor-plugin-base-test by amateescu:
    Followup for issue #2242493: Use exceptions instead of "return FALSE;"
    
  • Commit 6d05a25 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick, 2247923-Test_the_RenderedItem_processor, 2286813-fields-processor-plugin-base-test by drunken monkey:
    Follow-up to #2242493: Make sure exceptions from getBackend() are...
  • Commit 92c66f7 on master, views, htmlfilter, issue-2273743, 2268885-fix-validation, synonyms-processor, 2235381-fix-config-schemas-2, config-schema, transliteration, ignore-case-test-fix, ignorecase-nick, renamefields, highlight, add-aggregation-nick, 2247923-Test_the_RenderedItem_processor, 2286813-fields-processor-plugin-base-test by amateescu:
    Issue #2242493 by amateescu | drunken monkey: Use exceptions instead of...